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

Flutter代码陷入无限循环,无法正常渲染2个CategoryViewer

问题根源与修复方案

核心问题拆解

  • 方法循环调用导致列表无限膨胀:getHighProteinDrinks()内部调用了getHighFiberDrinks(),再加上initState里同时触发两个方法,drinkCategories会被反复添加重复组件。
  • GridView无终止构建条件:GridView.builder没设置itemCount,Flutter会持续调用itemBuilder;更关键的是,每次构建都执行getHighFiberDrinks(),这个方法又会往drinkCategories加元素,触发组件重建,形成死循环。
  • 冗余遍历完全无效:两个getXXXDrinks里的for循环纯属鸡肋,ListView.builder只需要一次初始化就能根据数据源长度生成列表,没必要遍历每个元素重复赋值。

修复后的完整代码

class CategoriesScreenCopy extends ConsumerStatefulWidget {
  const CategoriesScreenCopy({super.key});

  @override
  ConsumerState<CategoriesScreenCopy> createState() => _CategoriesScreenState();
}

class _CategoriesScreenState extends ConsumerState<CategoriesScreenCopy> {
  List<Widget> drinkCategories = [];

  Widget getHighProteinDrinks() {
    return ListView.builder(
      scrollDirection: Axis.horizontal,
      itemCount: highProteinDrinks.length,
      itemBuilder: (ctx, index) => DrinkItem(
        drink: highProteinDrinks[index],
      ),
    );
  }

  Widget getHighFiberDrinks() {
    return ListView.builder(
      scrollDirection: Axis.horizontal,
      itemCount: highFiberDrinks.length,
      itemBuilder: (ctx, index) => DrinkItem(
        drink: highFiberDrinks[index],
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    // 直接将两个分类组件添加到列表
    drinkCategories.add(getHighProteinDrinks());
    drinkCategories.add(getHighFiberDrinks());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 1,
          childAspectRatio: 3 / 3,
          crossAxisSpacing: 20,
          mainAxisSpacing: 8,
        ),
        // 绑定列表长度,限制GridView构建次数
        itemCount: drinkCategories.length,
        itemBuilder: (context, index) => CategoryViewer(
          categoryDrinkList: drinkCategories[index],
          // 根据索引匹配对应分类名称
          categoryDrinkName: index == 0 ? 'High-Protein Drinks' : 'High-Fiber Drinks',
        ),
      ),
    );
  }
}

关键修复说明

  • 切断循环调用链:getHighProteinDrinks()不再嵌套调用getHighFiberDrinks(),改为在initState里分别调用两个方法,将结果一次性加入drinkCategories。
  • 给GridView加终止条件:设置itemCount为drinkCategories.length,让GridView只构建你需要的2个组件。
  • 删掉无用的for循环:直接返回ListView.builder即可,它本身就能处理列表渲染逻辑。
  • 匹配正确的分类数据与名称:通过索引从drinkCategories取对应组件,并设置对应的分类名称,避免重复显示同一内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:37:29