Список виджетов безопасное состояние при использовании метода очистки

#flutter #flutter-layout

Вопрос:

У меня есть StatelessWidget, и я использую Провайдера. В моем классе провайдера у меня есть список виджетов:

 List<Widget> gridList= [];
 

Когда мой поставщик запущен, я вызываю метод init. В моем методе я заполняю gridList список виджетов:

   void listCheck(BuildContext context) {
    receiptFilterTypes.forEach((item) {
      gridList.add(
        Container(
          key: UniqueKey(),
          width: MediaQuery.of(context).size.width * 0.45,
          child: MyCheckBox(
            margin: EdgeInsets.all(0),
            title: item.name,
            selected: filter?.types?.contains(item) ?? false,
            onChanged: (value) {
              if (!(filter?.types?.contains(item) ?? false)) {
                filter.types.add(item);
              } else {
                filter.types.remove(item);
              }
            },
          ),
        ),
      );
    });
    notifyListeners();
  }
 

На моей странице у меня есть список галочек. Теперь я хочу, чтобы, когда пользователь нажимает на кнопку Select_All, он проверял все мои флажки. Итак, я написал этот метод:

   void selectAll(BuildContext context) {
    filter.types.clear();
    receiptFilterTypes.forEach((item) {
      filter.types.add(item);
    });
    gridList.clear();
    listCheck(context);
    notifyListeners();}
 

Проблема здесь в том, когда gridList очищается и я снова составляю список виджетов listCheck(context); после notifyListeners состояния

 MyCheckBox(
    margin: EdgeInsets.all(0),
    title: item.name,
    selected: filter?.types?.contains(item) ?? false,
 

Не изменился. Хотя selected это верно, но пользователь все равно видит флажок, не установленный.

Я исправил проблему, создав новый экземпляр gridList :

   void listCheck(BuildContext context) {
    gridList = []; //---- I added this
    receiptFilterTypes.forEach((item) {
      gridList.add(
        Container(
          key: UniqueKey(),
          width: MediaQuery.of(context).size.width * 0.45,
          child: MyCheckBox(
            margin: EdgeInsets.all(0),
            title: item.name,
            selected: filter?.types?.contains(item) ?? false,
            onChanged: (value) {
              if (!(filter?.types?.contains(item) ?? false)) {
                filter.types.add(item);
              } else {
                filter.types.remove(item);
              }
            },
          ),
        ),
      );
    });
    notifyListeners();
  }
 

Почему я должен создавать новый экземпляр gridList , и почему это gridList.clear() не работает?

Я использую свой список на главной странице следующим образом:

    Consumer<MyProvider>(
        builder: (context, model, child) 
      {
          return GridView.count(
            shrinkWrap: true,
            physics: NeverScrollableScrollPhysics(),
            crossAxisCount: 2,
            mainAxisSpacing: 3,
            crossAxisSpacing: 5,
            childAspectRatio: 3.5,
            children: model.gridList, //--> It's filled with new values but not working
          ),
 

Ответ №1:

Не вносите изменения в элементы списка в forEach , если вы хотите, чтобы изменения произошли с исходными объектами, которые у вас есть, Измените forEach в своей selectAll функции на цикл for

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

1. исходные объекты изменились, но виджет на моей странице после notifyListeners этого не изменился. Список верен, но не работает.

2. В вашем потребителе у вас есть model.gridList ценность, откуда она model берется?не следует ли вам использовать value поставщика, которого вы потребляете

3. Это была опечатка, братан, извини. Я это исправил