Неудачное утверждение: строка 4191 поз 14: «владелец!._debugCurrentBuildTarget == это’: неверно

#flutter #dart

Вопрос:

У меня есть два построителя представления списка, как показано на рисунке ниже, полученном из магазина fire:

введите описание изображения здесь

Ошибка при попытке получить конкретный список элементов, и это ошибка ниже:

 RangeError (index): Invalid value: Valid value range is empty: 4

When the exception was thrown, this was the stack: 
#0      List.[] (dart:core-patch/growable_array.dart:254:60)
#1      AppCubit.changeCategoryModelState (package:ipet/shared/cubit/cubit.dart:116:35)
#2      CategoriesScreen.buildPetsCategoryItem.<anonymous closure>.<anonymous closure> (package:ipet/modules/categories/categories_screen.dart:97:43)
#3      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#4      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:607:11)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#0916b
  debugOwner: GestureDetector
  state: ready
  won arena
  finalPosition: Offset(272.1, 219.8)
  finalLocalPosition: Offset(51.1, 42.8)
  button: 1
  sent tap down
 

So I want to when click on item from buildPetsCategoryItem() just Change the buildCategoriesListView()

So what is the best way to do this…

This is the below code:

         return SingleChildScrollView(
          controller: cubit.scrollController,
          physics: BouncingScrollPhysics(),
          child: Column(
            children: [
              SizedBox(
                height: 30,
              ),
              Padding(
                padding: const EdgeInsets.only(left: 20.0),
                child: CustomText(
                  text: "Categories",
                ),
              ),
              SizedBox(
                height: 30,
              ),
              // buildCategoryItem(context),
              buildPetsCategoryItem(context),
              buildCategoriesListView(cubit)
            ],
          ),
        );
 

to be more clear I have this below categoriesBuilder:

  Widget buildPetsCategoryItem(context) {
    return Container(
      height: 120,
      child: ListView.builder(
        physics: BouncingScrollPhysics(),
        scrollDirection: Axis.horizontal,
        itemCount: AppCubit.get(context).petsCategories.length,
        itemBuilder: (context, index) {
          return Container(
            padding: EdgeInsets.only(top: 20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                GestureDetector(
                  onTap: () {
                    AppCubit.get(context).changePetsCategoryBorder(index);
                    AppCubit.get(context).changeCategoryModelState(index);
                  },
                  child: Container(
                    width: 60,
                    height: 60,
                    margin: EdgeInsets.symmetric(horizontal: 18),
                    padding: EdgeInsets.all(12),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      boxShadow: customShadow,
                      border:
                          AppCubit.get(context).selectedPetsCategory == index
                              ? Border.all(
                                  color: secondaryGreen,
                                  width: 2,
                                )
                              : null,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Image.network(
                      AppCubit.get(context).petsCategories[index].image,
                      scale: 1.8,
                    ),
                  ),
                ),
                SizedBox(
                  height: 6,
                ),
                Text(
                  AppCubit.get(context).petsCategories[index].name,
                  style: TextStyle(fontSize: 12, color: Colors.grey),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
 

and this is the CategoriesListView:

   ListView buildCategoriesListView(AppCubit cubit) {
    return ListView.builder(
      shrinkWrap: true,
      physics: BouncingScrollPhysics(),
      // scrollDirection: Axis.horizontal,
      itemCount: cubit.currentCategoryPets.length,
      itemBuilder: (context, index) {
        return GestureDetector(
          onTap: () {
            navigateTo(
              context,
              DetailsScreen(
                pets: cubit.currentCategoryPets[index],
              ),
            );
          },
          child: Container(
            margin: EdgeInsets.symmetric(vertical: 5),
            child: PetCard(
              petId: cubit.currentCategoryPets[index].id,
              petName: cubit.currentCategoryPets[index].name,
              age: cubit.currentCategoryPets[index].age,
              breed: cubit.currentCategoryPets[index].petType,
              gender: cubit.currentCategoryPets[index].gender,
              distance: cubit.currentCategoryPets[index].distance,
              imagePath: cubit.currentCategoryPets[index].image,
            ),
          ),
        );
      },
    );
  }
 

as I have both methods which get the PetsModel data for each category one gets all the pets, and the other get the Cats one:

   List<PetsModel> pets = [];
  List<PetsModel> cats = [];
  void getPetsData() {
    FirebaseFirestore.instance.collection('pets').get().then((value) {
      value.docs.forEach((element) {
        pets.add(PetsModel.fromJson(element.data()));
      });
      emit(AppGetPetsSuccessState());
    }).catchError((error) {
      emit(AppGetPetsErrorState(error.toString()));
    });
  }

  void getCatsData() {
    FirebaseFirestore.instance.collection('pets').where('type', isEqualTo: 'cat').get().then((value) {
      value.docs.forEach((element) {
        cats.add(PetsModel.fromJson(element.data()));
      });
      emit(AppGetPetsSuccessState());
    }).catchError((error) {
      emit(AppGetPetsErrorState(error.toString()));
    });
  }
 

I tried to create a method that changes the Category Model State as the below one:

   PetsModel petModel;
  List<PetsModel> currentCategoryModel = [];

  void changeCategoryModelState(int position) {
    petModel = currentCategoryPets[position];
    if (position == 4) getPetsData();
    if (position == 5) getCatsData();
    emit(AppChangeCategoryModelState());
  }
 

this is the main class which contains the BlocProvider:

 return BlocProvider(
      create: (BuildContext context) => AppCubit()
        ..getUserData()
        ..getCategoriesData()
        ..getPetsData()
        ..getCatsData()
        ..handleScroll(),
      child: BlocConsumer<AppCubit, AppStates>(...),);
 

for more infos this is the pet card widget:

 @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    // final randomColor = colors[_random.nextInt(colors.length)];
    return Container(
      margin: EdgeInsets.symmetric(horizontal: 20),
      height: 240,
      child: Stack(
        children: [
          Container(
            // height: 200,
            margin: EdgeInsets.only(
              top: 70,
              bottom: 20,
            ),
            child: Row(
              children: [
                Container(
                  width: size.width * 0.48,
                ),
                Expanded(
                  child: Container(
                    margin: EdgeInsets.symmetric(horizontal: 10, vertical: 20),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            CustomText(
                              text: petName,
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              maxLine: 1,
                              overflow: TextOverflow.ellipsis,
                            ),
                            Icon(
                              gender == 'female'
                                  ? FontAwesomeIcons.venus
                                  : FontAwesomeIcons.mars,
                              size: 18,
                              color: Colors.black54,
                            )
                          ],
                        ),
                        Text(
                          breed,
                          style: TextStyle(
                            fontSize: 12,
                            color: fadedBlack,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                        CustomText(
                          text: age   ' years',
                          fontSize: 12,
                          color: fadedBlack,
                        ),
                        Row(
                          children: [
                            Icon(
                              Icons.location_pin,
                              size: 16,
                              color: primaryGreen,
                            ),
                            SizedBox(
                              width: 5,
                            ),
                            CustomText(
                              text: 'Distance: '   distance   ' Km',
                              fontSize: 12,
                              color: fadedBlack,
                            ),
                          ],
                        )
                      ],
                    ),
                  ),
                )
              ],
            ),
            decoration: BoxDecoration(
              color: Colors.white,
              boxShadow: customShadow,
              borderRadius: BorderRadius.only(
                topRight: Radius.circular(20),
                bottomRight: Radius.circular(20),
              ),
            ),
          ),
          Container(
            width: size.width * 0.48,
            child: Stack(
              children: [
                Container(
                  decoration: BoxDecoration(
                    color: Theme.of(context).scaffoldBackgroundColor,
                    boxShadow: customShadow,
                    borderRadius: BorderRadius.circular(22),
                  ),
                  margin: EdgeInsets.only(top: 50),
                ),
                Align(
                  child: Hero(
                    tag: petId,
                    child: Image.network(
                      imagePath,
                      loadingBuilder: loadingNetworkImage,
                    ),
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
 

the below method is related for selectedPetsCategories() :

   int selectedPetsCategory = 0;

  void changePetsCategoryBorder(int index) {
    selectedPetsCategory = index;
    emit(AppChangePetsCategoryBorderState());
  }
 

Как я могу устранить эту ошибку?

Отредактированный

Итак, за предыдущую ошибку, потому что я должен добавить changeCategoryModelState() метод init при запуске приложения в blocProvider, поэтому я сделал int position аргумент необязательным и попытался добавить метод addAll в качестве кода ниже:

   void changeCategoryModelState({int position}) {
    petModel = currentCategoryPets[position];
    if (position == 4) getPetsData();
    if (position == 5) getCatsData();
    currentCategoryPets.addAll(pets);
    emit(AppChangeCategoryModelState());
  }
 

и назвал его в основном, как показано ниже, кодом:

 return BlocProvider(
      create: (BuildContext context) => AppCubit()
        ..getUserData()
        ..getCategoriesData()
        ..getPetsData()
        ..getCatsData()
        ..changeCategoryModelState()
        ..handleScroll(),
      child: BlocConsumer<AppCubit, AppStates>(...),);
 

Я обнаружил следующую ошибку:

 E/flutter ( 4506): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 2651 pos 20: '_debugCurrentBuildTarget == context': is not true.
E/flutter ( 4506): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
The following assertion was thrown attaching to the render tree:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4191 pos 14: 'owner!._debugCurrentBuildTarget == this': is not true.


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

When the exception was thrown, this was the stack: 
#2      Element.rebuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4191:14)
#3      Element.rebuild (package:flutter/src/widgets/framework.dart:4194:6)
#4      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4474:5)
#5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4469:5)
#6      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
 

Комментарии:

1. Разве currentCategoryPets список не пуст при первом changeCategoryModelState() звонке?

2. @mkobuolys нет, я еще не пытался вызвать его, пока не создам другие методы, я просто хочу увидеть результат, так как другие категории в firestore также являются emty, предполагается, что категория » Все » — это позиция 4, а кошка-одна позиция 5

3. И что происходит внутри AppCubit.get(context).changePetsCategoryBorder(index); или AppCubit.get(context).changeCategoryModelState(index); ?

4. @mkobuolys первый метод изменяет радиус границы при выборе элемента, а другой метод должен дать мне модель категории, которую я выбираю

5. Так, может быть, второй метод вызывает элемент с индексом, который находится вне диапазона?

Ответ №1:

Это правильный ответ, тогда просто удалите аргументы и обновите changeCategoryModelState метод до:

   void changeCategoryModelState() {
    if (selectedPetsCategory == 5) {
      currentCategoryPets.clear();
      currentCategoryPets.addAll(cats);
      print(selectedPetsCategory.toString());
    }
    else if (selectedPetsCategory == 4) {
      currentCategoryPets.clear();
      currentCategoryPets.addAll(pets);
      print(selectedPetsCategory.toString());
    }
    emit(AppChangeCategoryModelState());
  }