You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

搜索场景下无限滚动分页失效问题排查及解决方案咨询

问题描述

实现带分页的搜索请求功能,在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,
        ),
      );
    },
  ),
),
问题原因与解决办法

核心问题

  1. 每次输入都调用addPageRequestListener,会重复添加多个监听器,导致逻辑混乱。
  2. 首次请求后,分页控制器处于已加载状态,关键词变化时没有重置控制器,无法触发新的第一页请求。
  3. _fetchPage函数存在语法错误(catch块位置不对),且列表赋值方式可能导致数据异常。

具体修复步骤

  1. 将监听器移到初始化阶段
    只在页面初始化时添加一次监听器,避免重复绑定:

    late String _currentSearchParam;
    
    @override
    void initState() {
      super.initState();
      _currentSearchParam = '';
      _pagingController.addPageRequestListener((pageKey) {
        _fetchPage(pageKey, _currentSearchParam.trim());
      });
    }
    
  2. 修改onChanged逻辑,重置分页控制器
    每次输入新关键词时,更新搜索参数并重置控制器,触发新的搜索请求:

    onChanged: (value) {
      _currentSearchParam = value;
      // 重置控制器,清空旧数据并重新请求第一页
      _pagingController.refresh();
    },
    
  3. 修复_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();
      }
    }
    
  4. 添加控制器销毁逻辑
    在页面销毁时清理分页控制器,避免内存泄漏:

    @override
    void dispose() {
      _pagingController.dispose();
      super.dispose();
    }
    

替代包推荐

如果当前分页包仍无法满足需求,可以尝试以下替代方案:

  • infinite_scroll_pagination:Flutter社区广泛使用的分页库,对搜索、筛选等场景支持完善,API设计更直观。
  • pull_to_refresh:提供下拉刷新和上拉加载的基础组件,可结合自定义分页逻辑实现需求,灵活性更高。

内容的提问来源于stack exchange,提问作者Samuel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:00:59