如何从另一个小部件设置状态?
问题内容:
我正在尝试从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中吗?
问题答案:
尽可能避免这种情况。这使得这些小部件彼此依赖,并且从长远来看会使事情变得更难维护。
相反,您可以做的是让两个小部件共享一个公共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
。