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

Flutter基于Future<void>实现分页时无限加载问题求助

问题排查与修复方案

核心问题分析

你的代码出现无限加载的原因主要有三点:

  1. FutureBuilder滥用导致重复请求:直接将fetchItems()传入FutureBuilder的future参数,每次组件build(比如setState后)都会重新执行fetchItems(),触发不必要的API请求,形成循环。
  2. 滚动监听缺少加载状态判断:滚动到底部的判断逻辑仅检查了hasMore,未排除isLoading状态,导致加载过程中只要滚动位置满足条件就会重复调用请求。
  3. shrinkWrap属性干扰滚动计算:GridView设置shrinkWrap: true会让列表高度自适应内容,可能导致maxScrollExtent计算不准确,频繁触发底部判断。

修复后的代码

构建方法修改

Widget build(BuildContext context) {
  return Center(
    child: NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification scrollInfo) {
        // 提前10%触发加载,同时排除加载中状态
        if (scrollInfo.metrics.pixels >= scrollInfo.metrics.maxScrollExtent * 0.9 &&
            hasMore &&
            !isLoading) {
          fetchItems();
        }
        return true;
      },
      child: _buildContent(),
    ),
  );
}

// 拆分UI构建逻辑,提升可读性
Widget _buildContent() {
  if (categoyItems == null || categoyItems!.isEmpty) {
    return isLoading
        ? const Center(child: CircularProgressIndicator())
        : const Center(child: Text('No states available'));
  }

  return GridView.custom(
    padding: const EdgeInsets.symmetric(vertical: 10),
    gridDelegate: const SliverStairedGridDelegate(
      mainAxisSpacing: 6,
      crossAxisSpacing: 8,
      pattern: [
        StairedGridTile(0.53, 0.8),
        StairedGridTile(0.470, 0.8),
        StairedGridTile(0.470, 0.8),
        StairedGridTile(0.53, 0.8),
      ],
    ),
    childrenDelegate: SliverChildBuilderDelegate(
      childCount: categoyItems!.length + (hasMore ? 1 : 0),
      (context, index) {
        if (index == categoyItems?.length) {
          return const Center(child: CircularProgressIndicator());
        }
        final item = categoyItems![index];
        return Container(....); // 保留你的原有组件逻辑
      },
    ),
  );
}

API请求方法无需修改(已具备加载状态控制)

你的fetchItems()方法已经通过isLoading做了防重复请求处理,无需改动。

关键修改点说明

  • 移除FutureBuilder:直接通过组件状态(isLoading、categoyItems)构建UI,避免每次build触发重复请求。
  • 优化滚动监听逻辑:添加!isLoading判断防止加载中重复请求;将触发时机改为滚动到90%位置,提升用户体验同时避免边界条件误触发。
  • 移除shrinkWrap: true:让GridView使用默认的滚动布局逻辑,保证滚动参数计算准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:33:14