basically i m updating list value that used in gridview, when i click on gridview card, i m changing color of that card. when i print color value it did changing but in gridview has no effect. Plz suggest me what to do? is my logic approach is wrong ?

class FilterDialog extends ModalRoute<void> {

   List<Grades> mGradeList = [];
   List<Styles> mStyleList = [];
   List<Types> mTypeList = [];
   List<Specials> mSpecialList = [];

   FilterDialog(this.mGradeList, this.mStyleList, this.mTypeList, this.mSpecialList);

      @override
      Widget buildPage(
        BuildContext context,
        Animation<double> animation,
        Animation<double> secondaryAnimation,
      ) {
        // This makes sure that text and other content follows the material style
        return Material(
          type: MaterialType.transparency,
          // make sure that the overlay content is not cut off
          child: SafeArea(
            child: _buildOverlayContent(context),
          ),
        );
      }

      Widget _buildOverlayContent(BuildContext context) {
        return new Container(
            padding: EdgeInsets.only(left: 15, right: 15),
            child: Column(
                children: <Widget>[
                    titleWidget("Grade"),  
                    gridViewWidget(mGradeList, 3, 2.2),

                    spaceWidget(),
                    titleWidget("Style"),  
                    gridViewWidget(mStyleList, 2, 3.5),

                    spaceWidget(),
                    titleWidget("Type"),  
                    gridViewWidget(mTypeList, 2, 3.5),

                    spaceWidget(),
                    titleWidget("Special"),  
                    gridViewWidget(mSpecialList, 2, 3.5),
                ],
              )
          );
      }

      Widget gridViewWidget(list, int count, double ratio) {
        return GridView.count(
          shrinkWrap: true,
          crossAxisCount: count,
          mainAxisSpacing: 2.0,
          crossAxisSpacing: 1.0,
          childAspectRatio: ratio,
          physics: new NeverScrollableScrollPhysics(),
          children: _getTiles(list)
        );
      }

      void _onTileClicked(int index, value, list){
        assert(index != null);
        assert(value != null);
        setState(() {
            list[index].setSelected(!value);
        });
        debugPrint("You tapped on item $index with $value");
      }

      // Get grid tiles
    List<Widget> _getTiles(list) {
      final List<Widget> tiles = <Widget>[];
      for (int i = 0; i < list.length; i++) {
        tiles.add(new GridTile(
              child: new Center(
                child: Container(
                  height: 35.0,
                  child: new RaisedButton(
                    onPressed: () => _onTileClicked(i, list[i]["selected"], list),
                    color: list[i]["selected"] ? backgroundColor : white, //here value not changing
                    shape: new RoundedRectangleBorder(
                        borderRadius:
                            new BorderRadius.circular(30.0)),
                    child: new Text(
                      list[i]["label"],
                      textAlign: TextAlign.center,
                      style: new TextStyle(
                        fontSize: 14.0,
                        color: Colors.grey,
                      ),
                    ),
                  ),
                ),
              ),
            ));
      }
      return tiles;
    }

class model:

class Grades {
    String label;
    bool selected;

    Grades(this.label, this.selected);

    void setSelected(bool val) {
        this.selected = val;
    }
}

some data:

var typeList = [{"label": "Crack", "selected": false}, {"label": "Face", "selected": false},
   {"label": "Slab", "selected": false}, {"label": "Multi-pitch", "selected": false} ];  

enter image description here


Solution 1: user1462442

Widget _buildOverlayContent(BuildContext context) {
gridViewWidget(mTypeList, 2, 3.5)

List<Widget> _getTiles(list) { onPressed: () => _onTileClicked(i, list[i]["selected"], list),

final typeList = [{"label": "Crack", "selected": false}, {"label": "Face", "selected": false}, {"label": "Slab", "selected": false}, {"label": "Multi-pitch", "selected": false}

Do you intent to use typeList as a global state? I think the variable should not have a final modifier.

https://www.dartlang.org/guides/language/language-tour

If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.

I am basing my answer on the fact that you are accessing the list[i]["selected"] as a map while you define Grades as a object.


Solution 2: soupjake

Your class has to extend StatefulWidget along with it having a State widget in order for you to use the setState() method. For example:

class FilterWidget extends StatefulWidget {
  @override
  _FilterWidgetState createState() => _FilterWidgetState();
}

class _FilterWidgetState extends State<FilterWidget> {
    //lists here

  @override
  Widget build(BuildContext context) {
    //build stuff here with setState() being used
  }
}

You can find more information here from the official docs.


Solution 3: Miolane Xii

I meet the same problem. My solution is to reconstruct the object you want to change in GridView. Do not update the item in list but reconstruct the list and update the item as you like. Maybe it work.

I guess that if the point of list is not changed, the GridView that includes it will not be changed.