一尘不染

如何从另一个小部件设置状态?

flutter

我正在尝试从Flutter中的其他窗口小部件更改状态。例如,在以下示例中,我将在几秒钟后设置状态。

这是该代码:

class _MyAppState extends State<MyApp> {

  int number = 1;

  @override
  void initState() {
    super.initState();
    new Future.delayed(new Duration(seconds: 5)).then((_) {
      this.setState(() => number = 2);
      print("Changed");
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new FlatButton(
          color: Colors.blue,
          child: new Text("Next Page"),
          onPressed: () {
            Navigator.of(context).push(new MaterialPageRoute(
              builder: (BuildContext context) => new StatefulBuilder(builder: (BuildContext context, setState) =>new MySecondPage(number))
            ));
          },
        ),
      ),
    );
  }
}

我尝试使用InheritedWidget,但是除非将其包装在顶层窗口小部件上,否则将无法正常工作,这对于我要执行的操作不可行(上面的代码是我要实现的功能的简化)。

关于实现此目标的最佳方法的任何想法是在Flutter中吗?


阅读 295

收藏
2020-08-13

共1个答案

一尘不染

尽可能避免这种情况。这使得这些小部件彼此依赖,并且从长远来看会使事情变得更难维护。

相反,您可以做的是让两个小部件共享一个公共Listenable或类似的名称,例如Stream。然后,小部件通过提交事件进行交互。

为了更容易编写,您还可以将Listenable/
Stream与分别组合,ValueListenableBuilder并且StreamBuilder两者都可以为您提供监听/更新部分。

一个简单的例子Listenable

class MyHomePage extends StatelessWidget {
  final number = new ValueNotifier(0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ValueListenableBuilder<int>(
        valueListenable: number,
        builder: (context, value, child) {
          return Center(
            child: RaisedButton(
              onPressed: () {
                number.value++;
              },
              child: MyWidget(number),
            ),
          );
        },
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  final ValueListenable<int> number;

  MyWidget(this.number);

  @override
  Widget build(BuildContext context) {
    return new Text(number.value.toString());
  }
}

请注意这里,我们如何在执行操作时自动更新UI,number.value++而无需调用setState

2020-08-13