简而言之,您应该使小部件观察状态。为此,您需要进行状态管理。
我的方法基于
Flutter Architecture Samples中解释的Provider以及
Flutter Docs。请参阅它们以获取更简洁的说明,但步骤或多或少如下:
- 使用小部件需要观察的状态定义您的状态模型。
- 您可以拥有多个状态,例如`data`和`isLoading`,以等待某些API过程。模型本身扩展了`ChangeNotifier`。
- 使用观察器类包装依赖于这些状态的小部件。
- 这可以是`Consumer`或`Selector`。
- 当您需要“重新加载”时,您基本上会更新这些状态并广播更改。
对于状态模型,该类看起来或多或少如下。请注意,`notifyListeners`会广播更改。
class DataState extends ChangeNotifier{
bool isLoading;
Data data;
Future loadData(){
isLoading = true;
notifyListeners();
service.get().then((newData){
isLoading = false;
data = newData;
notifyListeners();
});
}
}
现在讲解小部件。这将是非常基础的代码框架。
return ChangeNotifierProvider(
create: (_) => DataState()..loadData(),
child: ...{
Selector<DataState, bool>(
selector: (context, model) => model.isLoading,
builder: (context, isLoading, _) {
if (isLoading) {
return ProgressBar;
}
return Container(
child: Consumer<DataState>(builder: (context, dataState, child) {
return WidgetData(...);
}
));
},
),
}
);
状态模型的实例由ChangeNotifierProvider提供。Selector和Consumer分别监视状态,每个状态为isLoading
和data
。它们之间没有太大的区别,但是你如何使用它们取决于它们的构建器提供的内容。Consumer提供对状态模型的访问,因此对其直接下方的任何小部件调用loadData
更简单。
如果不是这样,您可以使用Provider.of
。如果我们想在从第二个屏幕返回时刷新页面,那么我们可以像这样做:
await Navigator.push(context,
MaterialPageRoute(
builder: (_) {
return Screen2();
));
Provider.of<DataState>(context, listen: false).loadData();