搜索场景下无限滚动分页失效问题排查及解决方案咨询
问题描述
实现带分页的搜索请求功能,在TextField的onChanged函数中触发GET请求,首次输入字符时功能正常,但再次输入无任何响应。
相关代码
onChanged函数
onChanged: (value) { _pagingController.addPageRequestListener( (pageKey) { _fetchPage(pageKey, val.trim()); }, ); },
_fetchPage函数
Future<void> _fetchPage(int pageKey, String searchParam) async { final results = await searchRepo.getCareers( isSearching: true, searchParam: searchParam, token: token, page: pageKey, ); hasNextPage = results['hasNextPage']; newItems.clear(); newItems = results['schools']; print(newItems.length); if (!hasNextPage) { _pagingController.appendLastPage(newItems); } else { final nextPageKey = pageKey + 1; _pagingController.appendPage(newItems, nextPageKey); } } catch (error) { _pagingController.error = error.toString(); } }
UI代码
PagedListView<int, dynamic>( shrinkWrap: true, pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate<dynamic>( itemBuilder: (context, item, index) { return ListTile( leading: InitialsAvatar(name: item.name), title: Text( item.name ?? 'n/a', style: theme.textTheme.bodyText1, ), subtitle: Text( item.category, style: theme.textTheme.labelMedium, ), ); }, ), ),
问题原因与解决办法
核心问题
- 每次输入都调用
addPageRequestListener,会重复添加多个监听器,导致逻辑混乱。 - 首次请求后,分页控制器处于已加载状态,关键词变化时没有重置控制器,无法触发新的第一页请求。
_fetchPage函数存在语法错误(catch块位置不对),且列表赋值方式可能导致数据异常。
具体修复步骤
将监听器移到初始化阶段
只在页面初始化时添加一次监听器,避免重复绑定:late String _currentSearchParam; @override void initState() { super.initState(); _currentSearchParam = ''; _pagingController.addPageRequestListener((pageKey) { _fetchPage(pageKey, _currentSearchParam.trim()); }); }修改onChanged逻辑,重置分页控制器
每次输入新关键词时,更新搜索参数并重置控制器,触发新的搜索请求:onChanged: (value) { _currentSearchParam = value; // 重置控制器,清空旧数据并重新请求第一页 _pagingController.refresh(); },修复_fetchPage函数
修正语法错误,优化数据处理逻辑:Future<void> _fetchPage(int pageKey, String searchParam) async { try { final results = await searchRepo.getCareers( isSearching: true, searchParam: searchParam, token: token, page: pageKey, ); hasNextPage = results['hasNextPage']; final newItems = results['schools']; print(newItems.length); if (!hasNextPage) { _pagingController.appendLastPage(newItems); } else { final nextPageKey = pageKey + 1; _pagingController.appendPage(newItems, nextPageKey); } } catch (error) { _pagingController.error = error.toString(); } }添加控制器销毁逻辑
在页面销毁时清理分页控制器,避免内存泄漏:@override void dispose() { _pagingController.dispose(); super.dispose(); }
替代包推荐
如果当前分页包仍无法满足需求,可以尝试以下替代方案:
- infinite_scroll_pagination:Flutter社区广泛使用的分页库,对搜索、筛选等场景支持完善,API设计更直观。
- pull_to_refresh:提供下拉刷新和上拉加载的基础组件,可结合自定义分页逻辑实现需求,灵活性更高。
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

