我正在尝试从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))
));
},
),
),
);
}
}
我尝试使用一个继承小部件
,但除非我把它包裹在我的顶级小部件上,否则这是行不通的(上面的代码是我试图实现的简化)。
关于在Flutter中实现这一目标的最佳方式有什么想法吗?
尽可能避免这种情况。它使这些小部件相互依赖,并使事情更难长期维护。
相反,您可以让两个小部件共享一个公共的Listable
或类似的东西,例如Stream
。然后小部件通过提交事件相互交互。
为了更轻松地编写,您还可以将Listable
/Stream
分别与ValueListenableBuilder
和StreamBuilder
结合起来,它们都为您完成了监听/更新部分。
一个带有Listable
的快速示例。
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
。
实际上,最有效的方法是在flutter中使用BLoC包,并从小部件树的顶部实现它,这样所有继承的小部件都可以使用相同的bloc。如果你以前使用过Android——它的工作方式类似于Android架构组件——你可以将数据和状态管理从UI中分离出来——所以你不会在UI中设置状态,而是使用块来管理状态。所以你可以设置和访问相同的数据——从任何继承自实现bloc的顶部小部件的小部件中,对于更复杂的应用程序来说,这是非常有用的。
这是你可以找到包的地方: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