setState不会在Flutter中更改gridview中的值

时间:2018-10-29 13:18:06

标签: gridview flutter setstate

基本上,我正在更新gridview中使用的列表值,当我单击gridview卡时,我正在更改该卡的颜色。当我打印颜色值时,它确实发生了变化,但是在gridview中却没有效果。请给我建议怎么办?我的逻辑方法错了吗?

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 Grades {
    String label;
    bool selected;

    Grades(this.label, this.selected);

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

一些数据:

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

enter image description here

3 个答案:

答案 0 :(得分:2)

您的类必须扩展 StatefulWidget 并带有 State 小部件,才能使用 setState()方法。例如:

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.

答案 1 :(得分:0)

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}

您是否打算将typeList用作全局状态? 我认为该变量不应具有最终修饰符。

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

  

如果您从未打算更改变量,请使用final或const,   代替var或除类型外。可以设置最终变量   只有一次; const变量是编译时常量。 (const)   变量是隐式最终的。)最终的顶级或类变量   首次使用时被初始化。

我基于您在将list[i]["selected"]定义为对象的同时访问Grades作为地图这一事实。

答案 2 :(得分:0)

我遇到同样的问题。我的解决方案是在GridView中重建要更改的对象。不要更新列表中的项目,而是根据需要重建列表并更新项目。也许可以。

我猜想,如果列表点未更改,包含它的GridView也不会更改。