【问题标题】:Set state for a button in a ListView为 ListView 中的按钮设置状态
【发布时间】:2021-10-24 13:27:28
【问题描述】:

我有一个输入页面来创建新的提醒。在此页面上,您将选择几个不同的变量(提醒类型、开始日期等) - 在这个阶段,我只是想让它适用于两个变量。

我创建了一个按钮对象,它包含一些文本、一个“isSelected”值(更改颜色以显示它被选中)和一个 onPress 回调。计划是使用循环为每个必要的选择选项创建其中一个按钮,然后将其输入 ListView,这样您就有了一个可滚动的选择选项列表。当您选择项目时,新提醒对象的属性将更新,颜色将变为选中状态。

当我单击按钮时,该值被选中(打印语句显示这一点)但按钮不会更改为新的 isSelected 值,尽管使用了 SetState。我在这里想念什么?是否可以像这样将按钮输入 ListView 并且仍然更新它们的状态?还是您需要另谋出路?

class AddReminder extends StatefulWidget {
  @override
  _AddReminderState createState() => _AddReminderState();
}

class _AddReminderState extends State<AddReminder> {
  String addReminder = "";

  Reminder newReminder = Reminder();

  @override
  List<Widget> getReminderTypesButton(
      String selectionName, List selectionOptions, var reminderVariable) {
    // create new list to add widgets to
    List<Widget> selectionOptionsWidgets = [];

    // loop through selection options and create buttons
    for (String selection in selectionOptions) {
      bool isSelectedValue = false;
      selectionOptionsWidgets.add(
        FullWidthButton(
          text: selection,
          isSelected: isSelectedValue,
          onPress: () {
            setState(() {
              reminderVariable = selection;
              isSelectedValue = true;
            });
            print(reminderVariable);
          },
        ),
      );
    }
    ;

    // return list of widgets
    return selectionOptionsWidgets;
  }

  Widget build(BuildContext context) {
    List<List<Widget>> newList = [
      getReminderTypesButton("Type", reminderTypesList, newReminder.type),
      getReminderTypesButton(
          "Frequency", repeatFrequencyTypesList, newReminder.repeatFrequency)
    ];

    List<Widget> widgetListUnwrap(List<List<Widget>> inputList) {
      //takes list of list of widgets and converts to widget list (to feed into list view)
      List<Widget> widgetsUnwrapped = [];
      for (var mainList in inputList) {
        for (var widgets in mainList) {
          widgetsUnwrapped.add(widgets);
        }
      }
      return widgetsUnwrapped;
    }

    return SafeArea(
      child: Container(
        color: Colors.white,
        child: Column(
          children: [
            Hero(
                tag: addReminder,
                child: TopBarWithBack(
                  mainText: "New reminder",
                  onPress: () {
                    Navigator.pop(context);
                  },
                )),
            Expanded(
              child: Container(
                child: ListView(
                  children: widgetListUnwrap(newList),
                  shrinkWrap: true,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

这是我参考的列表

List<String> reminderTypesList = [
  "Appointment",
  "Check-up",
  "Other",
];

List<String> repeatFrequencyTypesList = [
  "Never",
  "Daily",
  "Weekly",
  "Monthly",
  "Every 3 months",
  "Every 6 months",
  "Yearly",
];

List<List<String>> selectionOptions = [
  reminderTypesList,
  repeatFrequencyTypesList
];

【问题讨论】:

    标签: flutter listview


    【解决方案1】:

    你的状态没有改变的原因是每次你调用setState(),整个build函数都会再次运行。如果您在build 方法中启动一个状态(在本例中为isSelectedValue)(因为在build 中调用了getReminderTypesButton()),代码将一次又一次地运行以下行,将状态重置为初始值。

    bool isSelectedValue = false;
    

    无论您调用多少次setState,此行将始终将isSelectedValue 设置为false

    为了避免这种情况,您需要将状态放在build 方法之外,最好是在FullWidthButton 中,如下所示:

    class FullWidthButton extends StatefulWidget {
      const FullWidthButton({Key? key}) : super(key: key);
    
      @override
      _FullWidthButtonState createState() => _FullWidthButtonState();
    }
    
    class _FullWidthButtonState extends State<FullWidthButton> {
      
      bool isSelectedValue = false;
      
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: () => setState(() => isSelectedValue = !isSelectedValue),
          // ...other lines
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2013-08-31
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多