Flutter中Navigator.pop()返回后如何重载刷新FutureBuilder组件
实现方法
核心问题是FutureBuilder不会自动感知路由返回事件,且你当前直接将请求方法写在future参数中,既无法主动控制刷新时机,还会在页面每次重绘时重复发起无意义请求。按以下步骤修改即可:
第一步:将列表请求的Future存入组件状态,不要直接内嵌在FutureBuilder参数中
在原列表页的State类中新增状态变量,在初始化生命周期中发起第一次数据请求,同时抽离独立的刷新方法:late Future<List<Incoming>> _listFuture; @override void initState() { super.initState(); // 首次进入页面拉取数据 _listFuture = UserApiService.getAllHelp(); } void _refreshData() { setState(() { // 重新发起请求,更新future状态触发FutureBuilder重绘 _listFuture = UserApiService.getAllHelp(); }); }第二步:修改FutureBuilder的future配置,替换为定义好的状态变量
ListView( scrollDirection: Axis.vertical, shrinkWrap: true, children: <Widget>[ Flexible( child: FutureBuilder<List<Incoming>>( future: _listFuture, // 替换为状态变量 builder: (context, snapshot) { if (snapshot.hasError) { return Text('Error ${snapshot.error}'); } if (snapshot.hasData) { streamController.sink.add(snapshot.data!.length); return gridView(snapshot); } return circularPogress(); }, )), ], );第三步:修改跳转逻辑,等待弹窗关闭后触发刷新
给goToProceed方法加async关键字,await等待路由返回结果,回到当前页后直接调用刷新方法即可:goToProceed(BuildContext context, Incoming incoming) async { await Navigator.push( context, MaterialPageRoute( fullscreenDialog: true, builder: (BuildContext context) => HelperProceedIncom(incoming: incoming) ) ); // 弹窗关闭后执行刷新 _refreshData(); }
可选优化
如果不需要每次弹窗关闭都刷新,仅在数据确实修改成功后才刷新,可以利用Navigator.pop的传参做判断:
- 二级弹窗页中,数据更新成功后调用pop时传入标识参数:
// 数据更新提交成功后执行 Navigator.pop(context, true); // 如果没做修改直接关闭,不传参数或者传false即可 // Navigator.pop(context); - 跳转方法中接收返回值,仅当返回值为
true时触发刷新:goToProceed(BuildContext context, Incoming incoming) async { final isUpdated = await Navigator.push( context, MaterialPageRoute( fullscreenDialog: true, builder: (BuildContext context) => HelperProceedIncom(incoming: incoming) ) ); if (isUpdated == true) { _refreshData(); }
}
> 额外提示:你当前的列表嵌套结构存在冗余,外层`ListView`包裹内部`Column`的写法容易引发滑动冲突,后续可以直接去掉外层冗余的`ListView`和`Flexible`嵌套,直接将`FutureBuilder`作为页面根组件即可,不影响本次刷新功能。 内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

