如何在showModalBottomSheet中使用setState

26

在BottomSheet中,我们是否有任何限制无法更新小部件状态?正如您在下面的示例中所看到的,我正在使用Switch,但其显示不会改变,尽管值已更新,只是它没有重新呈现。

现在,这是StatefulWidget的一部分。

我在DropdownButton小部件中也遇到了同样的问题。这两个在普通页面上都可以正常工作。

有人有什么想法吗?

showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
    return BottomSheet(
      onClosing: () {},
      builder: (BuildContext context) {
        return Switch(
          onChanged: (bool v) {
            debugPrint('v is ${v.toString()}');
            // b = v; <<-- This is also not working when using StatelessWidget
            setState(() => b = v);
            debugPrint(b.toString());
          },
          value: b,
        );
      },
    );
  },
);

请查看我对类似问题的回答:https://dev59.com/V7Tma4cB1Zd3GeqP1R95#56321614 - George Zvonov
2个回答

77
问题在于您创建的 BottomSheet 不是您的 StatefulWidget 的一部分。如果您只是为了在 showModalBottomSheet 中使用 setState 而使您的小部件有状态,那么现在可以撤销该更改。 你真正想做的是在你的 BottomSheet 中设置状态。 您可以通过将 StatefulWidget 传递给 builder 或使用 StatefulBuilder 来实现这一点,出于简单起见,在此示例中我将使用 StatefulBuilder
showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
    return BottomSheet(
      onClosing: () {},
      builder: (BuildContext context) {
        bool b = false;
        return StatefulBuilder(
          builder: (BuildContext context, setState) => Switch(
            onChanged: (bool v) {
              setState(() => b = v);
            },
            value: b,
          ),
        );
      },
    );
  },
);

我还将b的值移至BottomSheetbuilder函数内。

如果想在原始的StatefulWidget中使用b的值,您需要再次将其移出,并且可能需要调用this.setState来更新其他小部件(只有在需要更新时才这样做)。


谢谢。我本来想传递StatefulWidget,但这样也可以。不过,我同时使用了BLOC来更新小部件。 - Manvendra SK
1
谢谢。正是我所需要的。非常简单。 - Erik Basañez

25

我也遇到了同样的问题。这是一个小技巧,你需要在showModalBottomSheet中插入StatefulBuilder。现在我将使用不同的代码,用复选框让某个人更容易理解,即使答案来得很晚。

showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    builder: (BuildContext context) {
    mpesachecked =false;
    return StatefulBuilder(builder: (BuildContext context, StateSetter mystate) {
          return Padding(
          padding: const EdgeInsets.fromLTRB(10.0, 70.0, 20.0, 20.0),
          child: Column(
            children: <Widget>[
                 Checkbox(
                      value: mpesachecked,
                      activeColor: Colors.green,
                      onChanged: (value) {
                        mystate(() {
                          mpesachecked = value;
                        });
                      }),
                 ])
                 ));
               });
    )

注意:在 showModalBottomSheet 中,新的状态mystate


这是正确的!工作了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接