Flutter infinite_scroll_pagination下拉刷新数据重复问题求助
问题解决:下拉刷新数据重复加载
核心问题分析
- 重复注册请求监听:
initState中两次调用_pagingController.addPageRequestListener,导致同一页请求被触发多次,数据重复加载。 - 刷新逻辑冗余:
_refreshList里用setState包裹_pagingController.refresh()完全没必要,refresh()本身会自动通知UI更新。 - 状态赋值逻辑错误:直接将
listingState.itemList赋值给_pagingController.value.itemList,刷新时若Bloc未重置数据,旧数据会与新数据叠加。 - 加载状态控制混乱:
_isLoadingStarted的逻辑未正确重置,导致后续加载状态判断失效。
修复后的代码
class _AdListSliverGridState extends State<AdListSliverGrid> { final AdListSliverGridBloc _bloc = AdListSliverGridBloc(); final PagingController<int, AdListSummary> _pagingController = PagingController(firstPageKey: 0); late StreamSubscription _blocListingStateSubscription; @override void initState() { // 仅保留一个页面请求监听 _pagingController.addPageRequestListener((pageKey) { _bloc.onPageRequestSink.add(pageKey); }); _blocListingStateSubscription = _bloc.onNewListingState.listen((listingState) { // 区分刷新/首次加载和分页加载逻辑 if (listingState.nextPageKey == 0) { // 刷新或首次加载时直接替换数据 _pagingController.value = PagingState( nextPageKey: listingState.nextPageKey, error: listingState.error, itemList: listingState.itemList, ); } else { // 分页加载时使用appendPage追加数据,而非直接替换状态 if (listingState.itemList != null) { _pagingController.appendPage( listingState.itemList!, listingState.nextPageKey, ); } } }); super.initState(); } Future<void> _refreshList() async { // 直接调用refresh方法即可,无需setState _pagingController.refresh(); print('Refresh....'); } @override void dispose() { _pagingController.dispose(); _blocListingStateSubscription.cancel(); _bloc.dispose(); super.dispose(); } @override Widget build(BuildContext context) => RefreshIndicator( onRefresh: _refreshList, child: CustomScrollView( slivers: <Widget>[ PagedSliverGrid<int, AdListSummary>( pagingController: _pagingController, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( childAspectRatio: 0.810, crossAxisCount: 2, mainAxisSpacing: 5, crossAxisSpacing: 5, ), builderDelegate: PagedChildBuilderDelegate<AdListSummary>( itemBuilder: (context, item, index) => AdListGridItem( adlist: item, press: () { // 点击逻辑 }, ), ), ), ], ), ); }
额外注意事项
- Bloc层配合调整:确保
_pagingController.refresh()触发后,AdListSliverGridBloc收到pageKey=0的请求时,会重新从服务器拉取第一页数据,同时清空之前缓存的列表数据。 - 规范状态更新方式:除刷新/首次加载场景,分页加载时必须使用
appendPage方法添加新数据,避免直接覆盖PagingState,保证插件内部状态同步正确。
内容的提问来源于stack exchange,提问作者86as
相关产品推荐
相关产品推荐

