Flutter如何在FutureBuilder执行完成后刷新AppBar的标题
实现方案
完全可以实现,以下是两种可直接落地的实现方式:
方案1:在FutureBuilder内更新(最小改动适配现有代码)
在FutureBuilder的builder回调中判断异步状态,通过帧回调延迟执行状态更新,避免构建过程中触发状态修改异常。
修改后的代码如下:
class _SimpleBarChart extends State<SimpleBarChartPage> { String _appBarTitle = ''; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(_appBarTitle)), body: Center(child: futureCAGraph())); } futureCAGraph() { return FutureBuilder( future: BddAMKGraphCA().getDataGraphCA(_caAnnee), builder: (context, AsyncSnapshot<List<dynamic>> snapshot) { if (snapshot.hasData) { // 异步完成后更新标题 WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { // 可根据snapshot.data自定义标题内容 _appBarTitle = "数据加载完成,共${snapshot.data!.length}条"; }); }); return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, int currentIndex) { return affGraphCA(context); }); } else if (snapshot.hasError) { // 加载出错时也可更新标题 WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { _appBarTitle = "加载失败"; }); }); return Text('${snapshot.error}'); } // 加载中默认显示原有空标题,也可自定义加载中标题 return const CircularProgressIndicator(); }); } }
方案2:提前缓存Future(更推荐的最佳实践)
将异步请求缓存在State中,避免每次组件重绘都重复发起请求,同时直接在异步回调中更新标题,逻辑更清晰:
class _SimpleBarChart extends State<SimpleBarChartPage> { String _appBarTitle = '加载中...'; // 缓存异步请求 late Future<List<dynamic>> _graphFuture; @override void initState() { super.initState(); _graphFuture = BddAMKGraphCA().getDataGraphCA(_caAnnee); // 直接监听异步结果更新标题 _graphFuture.then((data) { setState(() { _appBarTitle = "数据加载完成,共${data.length}条"; }); }).catchError((err) { setState(() { _appBarTitle = "加载失败"; }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(_appBarTitle)), body: Center(child: futureCAGraph())); } futureCAGraph() { return FutureBuilder( // 复用缓存的Future,不会重复发起请求 future: _graphFuture, builder: (context, AsyncSnapshot<List<dynamic>> snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, int currentIndex) { return affGraphCA(context); }); } else if (snapshot.hasError) { return Text('${snapshot.error}'); } return const CircularProgressIndicator(); }); } }
注意事项
- 禁止在组件构建过程中同步调用
setState,会触发Flutter状态更新异常,必须通过addPostFrameCallback将更新操作延迟到当前帧绘制完成后执行。 - 异步请求缓存到State中可以避免不必要的重复请求,是官方推荐的
FutureBuilder最佳使用方式。
内容的提问来源于stack exchange,提问作者PO JP
相关产品推荐
相关产品推荐

