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

Flutter点击all按钮拉取Firestore列表触发RangeError索引越界问题

问题根因&修复方案

1. 最直接的RangeError报错原因:ListView.builder的itemCount变量写错

你当前代码里写的是itemCount: filteredUsers.length,但你实际用来渲染的数据源是filteredTests,变量名写错导致列表长度取错,当filteredTests长度大于filteredUsers时就会触发索引越界,所以只展示前4条、报0..3:4的错误。
你需要把这个值改成filteredTests.length(如果不需要底部加载状态就直接用这个值,如果要保留加载提示就改成filteredTests.length + 1)。

2. Card样式匹配错误原因:_card方法逻辑写反

你现在是判断整个列表里是否存在某类数据,存在就给所有条目返回同一种Card,完全没有判断当前索引对应条目的真实类型。正确逻辑应该是判断当前index对应条目的type字段返回对应样式,同时用模运算避免颜色数组越界:

Widget _card(int index) {
  // 先拿到当前条目
  final currentItem = filteredTests[index];
  // 判断当前条目的type
  if (currentItem.type.toLowerCase().contains('باقة')) {
    return PackageCardDesign(
      packageName: currentItem.name,
      price: '${currentItem.price} YR',
      details: currentItem.details.toLowerCase(),
      // 用模运算避免颜色数组长度不足触发越界
      colour: Packgecolors[index % Packgecolors.length],
      icon: Icons.ac_unit_outlined,
      type: currentItem.type,
    );
  } else if (currentItem.type.toLowerCase().contains('تحليل')) {
    return TestCardDesign(
      colour: TestOffercolors[index % TestOffercolors.length],
      testName: currentItem.name,
      details: currentItem.details.toLowerCase(),
      price: '${currentItem.price} YR',
      type: currentItem.type,
    );
  } else if (currentItem.type.toLowerCase().contains('عرض')) {
    return OfferCardDesign(
      colour: TestOffercolors[index % TestOffercolors.length],
      testName: currentItem.name,
      price: '${currentItem.price} %',
    );
  }
  // 兜底返回空容器避免空指针报错
  return const SizedBox.shrink();
}

3. 初始加载数据不显示的修复

initState阶段tests还是空列表,你需要在build方法里拿到Provider的tests之后,初始化filteredTests:

@override
Widget build(BuildContext context) {
  tests = Provider.of<List<Test>>(context);
  // 增加这行:首次拿到数据时初始化筛选列表
  if (filteredTests.isEmpty && tests.isNotEmpty) {
    filteredTests = tests;
  }
  // 其余原有代码不变
  ...
  // 修改ListView.builder的配置
  ListView.builder(
    shrinkWrap: true,
    padding: EdgeInsets.all(10.0),
    controller: scrollController,
    scrollDirection: Axis.vertical,
    // 修改为正确的数据源长度
    itemCount: filteredTests.length,
    itemBuilder: (BuildContext context, int index) {
      return Card(
        child: Padding(
          padding: EdgeInsets.all(10.0),
          child:_card(index)
        ),
      );
    },
  )
}

4. 可选优化:点击全量按钮时重置顶部分类筛选状态

你当前点击字母栏的「الكل」按钮时,只重置了数据源,没有重置顶部三个分类按钮的selectedButton状态,会出现筛选状态和展示数据不匹配的问题,修改点击逻辑:

if (alphabets[i] == 'الكل') {
  filteredTests = tests;
  // 增加这行重置分类筛选状态
  selectedButton = null;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:45:05