Flutter中如何在FutureBuilder内使用RefreshIndicator
Flutter FutureBuilder 结合 RefreshIndicator 下拉刷新失效的解决方法
你的代码存在三个核心问题导致下拉刷新不生效:
FutureBuilder 的 future 未绑定状态
直接把SupervisorServices.getWorkersList()写在FutureBuilder的future参数中,每次组件重建都会重复发起请求。更关键的是,下拉刷新时调用该方法后,没有更新FutureBuilder依赖的future实例,所以数据不会重新渲染。ListView 禁用了滚动交互
ListView.builder设置了physics: const NeverScrollableScrollPhysics(),而RefreshIndicator依赖子组件的滚动手势来触发刷新逻辑,这直接导致刷新手势无法被识别。缺少状态驱动的重建机制
当前代码未使用StatefulWidget管理future的状态,刷新后无法通知FutureBuilder重新构建界面。
修复方案
1. 改用StatefulWidget管理future状态
将组件改为StatefulWidget,在state类中持有future实例,初始化时加载数据,下拉刷新时更新该实例并触发setState。
2. 恢复ListView的滚动物理
移除NeverScrollableScrollPhysics,或替换为AlwaysScrollableScrollPhysics(),确保ListView能响应滚动手势。
3. 正确实现刷新回调
在onRefresh中重新发起请求,更新state中的future,并等待请求完成以确保刷新指示器状态正确。
修改后的完整代码示例
class WorkerListPage extends StatefulWidget { const WorkerListPage({super.key}); @override State<WorkerListPage> createState() => _WorkerListPageState(); } class _WorkerListPageState extends State<WorkerListPage> { late Future<List<dynamic>> _workersFuture; @override void initState() { super.initState(); _workersFuture = SupervisorServices.getWorkersList(); } Future<void> _refreshWorkers() async { setState(() { _workersFuture = SupervisorServices.getWorkersList(); }); await _workersFuture; } @override Widget build(BuildContext context) { return Column( children: [ const Heading("New Workers !"), // ListView嵌套在Column中时,用Expanded包裹避免布局约束问题 Expanded( child: FutureBuilder( future: _workersFuture, builder: (context, snapshot) { if (snapshot.hasData) { final data = snapshot.data!; return RefreshIndicator( onRefresh: _refreshWorkers, child: ListView.builder( itemCount: data.length, physics: const AlwaysScrollableScrollPhysics(), itemBuilder: (context, index) { return Card( child: ListTile( leading: const SizedBox( height: double.infinity, child: Icon(FeatherIcons.user), ), // 补充你的ListTile其他内容 ), ); }, ), ); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } return const Center(child: CircularProgressIndicator()); }, ), ), // 其他组件 ], ); } }
额外注意事项
- 如果ListView嵌套在Column中,务必用
Expanded包裹,否则会出现布局溢出或滚动异常。 - 确认
SupervisorServices.getWorkersList()方法每次调用都会返回最新数据(而非缓存结果),否则刷新后界面不会有变化。
内容的提问来源于stack exchange,提问作者swapnil mane
相关产品推荐
相关产品推荐

