Flutter Widget 006: FutureBuilde
2021-03-22 本文已影响0人
狂奔的胖蜗牛
1.概要
大多数情况下,我们的一个页面是需要根据网络请求返回的结果来决定是如何显示的,比如网络请求失败时显示请求失败,无网络时显示无网络,请求中显示请求中等等需求。这些需求,我们都是可以通过网络请求的Future来实现,但是,Flutter给我们提供了一个非常方便的FutureBuilder来实现根据Future状态来实现界面的方式。
在FutureBuilder的builder里面,我们能够根据当前状态来实现界面的显示内容。
2.源码
FutureBuilder({
Key key,
// 指定的耗时任务
this.future,
// 初始化的数据,可用于设置默认数据
this.initialData,
// Widget构造器,会被多次执行,在该构造器内,我们可以实现根据不同的状态,实现不同界面内容的显示
@required this.builder,
})
3.示例
Widget build(BuildContext context) => FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
debugPrint('构建Widget: ${snapshot.data}');
// 通过数据构建界面
return Center(child: Container(child: Text('hasData: ${snapshot.data}')));
} else {
// 显示加载Loading,直到数据返回时停止
debugPrint('构建加载Loading');
return CircularProgressIndicator();
}
},
);
Future<bool> fetchData() => Future.delayed(Duration(seconds: 1), () {
debugPrint('拉取数据');
return true;
});
我们可以通过snapshot.connectionState属性,获取到当前future当前处于哪个状态,分别有:
- none:当前没有Future在执行,比如future为nil。
- waiting:Future执行中。
- active:执行完毕,数据已经返回,但是future还未结束。
- done:执行完毕,数据已返回,future也结束了。
可以通过snapshot.hasData来判断future是否返回非null的值。如果说future定义的时候,返回的就是void,那么snapshot.hasData将一直为false。
可以通过snapshot. hasError来判断future是否返回了非null的错误。
4.注意事项
如果说我们照着示例那么写,future是通过fetchData方法返回的,那么,当我们在某个地方调用setState()后,会导致页面重新去执行一次fetchData方法。如果说,我们的需求不是这样的,该页面只是需要执行一次,那么,我们就应该把fetchData返回的Future设为一个属性,在FutureBuilder构建时,传入该属性。这样就能避免上述问题。
class _MyHomePageState extends State<MyHomePage> {
Future<bool> _data;
@override
void initState() {
super.initState();
// 这里,将fecthData返回的Future用属性存储起来
_data = fetchData();
}
@override
Widget build(BuildContext context) => FutureBuilder(
initialData: false,
future: _data,
...
);
...
Future<bool> fetchData() => Future.delayed(Duration(seconds: 1), () {
return true;
});
}