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

时间:2018-05-19 23:11:18

标签: dart 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?

2 个答案:

答案 0 :(得分:27)

尽可能避免这种情况。这使得这些小部件依赖于彼此,并且可以使事情在长期内更难维护。

您可以做的是让两个小部件共享一个共同的Listenable或类似的内容,例如Stream。然后,小部件通过提交事件相互交互。

为了便于撰写,您还可以将Listenable / Stream分别与ValueListenableBuilderStreamBuilder合并,这两者都会为您提供收听/更新部分。

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());
  }
}

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

答案 1 :(得分:5)

实际上,最有效的方法是在flutter中使用BLoC包,并从小部件树的顶部实施它,以便所有继承的小部件都可以使用同一块。如果您以前使用过Android(其工作原理类似于Android Architecture组件),则将数据和状态管理与UI分开了,因此您无需在UI中设置setState,而是使用块来管理状态。因此,您可以设置和访问相同的数据-从继承了实现集团的顶级窗口小部件继承的任何窗口小部件,对于更复杂的应用程序,它非常有用。

您可以在这里找到软件包:https://pub.dev/packages/flutter_bloc#-readme-tab-

编写:https://www.didierboelens.com/2018/08/reactive-programming-streams-bloc/

关于youtube https://www.youtube.com/watch?v=hTExlt1nJZI&list=PLB6lc7nQ1n4jCBkrirvVGr5b8rC95VAQ5&index=7的精彩教程