List of widgets safe it's state when use clear method

Viewed 31

I have a StatelessWidget and I am using Provider. In my provider class I have a list of widget:

List<Widget> gridList= [];

When my provider is started, I call the init method. In my method, I fill gridList by list of widget:

  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();
  }

In my page, I have a list of MyCheckBox. Now, I want, when user taps on Select_All button, to check all MyCheckBox. So, I wrote this method:

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

The problem is here, when gridList is cleared and I made again list of widget listCheck(context); after notifyListeners the state of

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

Not changed. Although selected is true but user still see a checkbox not selected.

I fixed the problem by creating a new instance of 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();
  }

Why do I have to create a new instance of gridList, and why does gridList.clear() not work?

I am using of my list in main page like this:

   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 Answers

Don't make changes to your list items in forEach if you want the changes to happen on the original objects you have Change the forEach in your selectAll function to a for loop

Related