setState не изменяет значение в gridview во флаттере - PullRequest
0 голосов
/ 29 октября 2018

В основном я обновляю значение списка, которое используется в 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 голосов
/ 01 ноября 2018

Ваш класс должен расширять 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
  }
}

Более подробную информацию вы можете найти здесь в официальных документах.

0 голосов
/ 24 ноября 2018

Я встречаю ту же проблему. Мое решение состоит в том, чтобы восстановить объект, который вы хотите изменить в GridView. Не обновляйте элемент в списке, а восстанавливайте список и обновляйте элемент, как вам нравится. Может быть, это работает.

Полагаю, что если точка списка не изменилась, включающий ее GridView не изменится.

0 голосов
/ 31 октября 2018
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 переменные неявно являются окончательными.) Последняя переменная верхнего уровня или класса инициализируется при первом использовании.

Я основываю свой ответ на том факте, что вы обращаетесь к list[i]["selected"] как карте, а вы определяете Grades как объект.

...