Flutter切换分类列表时出现RangeError及断言错误如何解决
错误原因与解决方案
1. 初始RangeError问题解决
该报错的核心原因是changeCategoryModelState方法逻辑错误:你在方法第一行就访问空列表currentCategoryPets的指定下标,此时列表还没有任何数据,直接触发越界,且这行赋值给petModel的代码完全没有被使用,属于无用逻辑。
正确的修改如下:
// 改回必传position参数,不需要可选 void changeCategoryModelState(int position) { // 直接删除无用的 petModel = currentCategoryPets[position]; 行 if (position == 4) { // 把已拉取的全量宠物数据赋值给当前展示列表 currentCategoryPets = List.from(pets); } else if (position == 5) { // 把已拉取的猫类数据赋值给当前展示列表 currentCategoryPets = List.from(cats); } else { // 其他分类逻辑自行补充,默认给空列表 currentCategoryPets = []; } emit(AppChangeCategoryModelState()); }
同时修正数据拉取方法,避免重复加载数据,且默认首次加载后展示全量宠物:
void getPetsData() { FirebaseFirestore.instance.collection('pets').get().then((value) { // 每次拉取先清空旧数据,避免重复添加 pets.clear(); value.docs.forEach((element) { pets.add(PetsModel.fromJson(element.data())); }); // 默认首次加载完成后展示全量宠物 currentCategoryPets = List.from(pets); emit(AppGetPetsSuccessState()); }).catchError((error) { emit(AppGetPetsErrorState(error.toString())); }); } void getCatsData() { FirebaseFirestore.instance.collection('pets').where('type', isEqualTo: 'cat').get().then((value) { cats.clear(); value.docs.forEach((element) { cats.add(PetsModel.fromJson(element.data())); }); emit(AppGetPetsSuccessState()); }).catchError((error) { emit(AppGetPetsErrorState(error.toString())); }); }
2. 修改后新的断言错误解决
该报错的原因是你在BlocProvider的create方法中同步调用了changeCategoryModelState(),这个方法会触发状态emit,而此时对应的BlocConsumer组件还在挂载构建阶段,构建过程中触发重建就会触发Flutter的框架断言。
直接删掉BlocProvider初始化代码中的..changeCategoryModelState()调用即可:
return BlocProvider( create: (BuildContext context) => AppCubit() ..getUserData() ..getCategoriesData() ..getPetsData() ..getCatsData() ..handleScroll(), child: BlocConsumer<AppCubit, AppStates>(...), );
可选优化建议
如果后续分类数量较多,可以改成点击对应分类时再异步拉取对应分类的数据,减少首次初始化的请求压力:判断对应分类的列表为空时再发起请求,请求成功后再赋值给currentCategoryPets即可。
内容的提问来源于stack exchange,提问作者Mahmoud Al-Haroon
相关产品推荐
相关产品推荐

