【问题标题】:setState not changing value in gridview in fluttersetState 在颤动中不改变gridview中的值
【发布时间】:2019-04-02 10:26:58
【问题描述】:

基本上我正在更新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} ];  

【问题讨论】:

  • 你不应该在ModalRoute 中创建你的用户界面。您应该将其移至小部件
  • @RémiRousselet 我明白这一点,但是 ModalRoute 有什么办法吗? bcz 要求是在透明的全屏对话框中制作过滤视图。
  • _buildOverlayContent 应该传递给构造函数而不是方法

标签: gridview flutter setstate


【解决方案1】:

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

我猜如果list的点不改变,包含它的GridView也不会改变。

【讨论】:

    【解决方案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.

    【讨论】:

    • setState 工作正常.. 我不能使用 StatefulWidget 因为它的对话框模式类,而且我每次都得到更新的值,它对 gridview 没有影响
    • setState 中的逻辑会改变值,但 setState 的点是notify the framework that the internal state of this object has changed.。由于您的 Widget 不是有状态或扩展状态,因此 setState() 方法将不起作用。请问您为什么要扩展 ModalRoute 类?
    • 因为过滤视图应该在透明对话框中。这就是我使用 ModalRoute 类的原因。有没有其他方法可以使用 statfulwidget 进行透明对话。
    • 你可以使用 Colors.black.withOpacity(0.8) (你想要的任何值)或 Colors.transparent 作为颜色道具一个 Scaffold 或 Material 小部件以获得透明/玻璃般的效果。也许试一试?
    • 它适用于 StatefulWidget,但不适用于 ModalRoute。谢谢你让我大开眼界。现在唯一剩下的问题是让页面透明..我想没有 ModalRoute 是不可能的。
    【解决方案3】:
    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 用作全局状态? 我认为变量不应该有 final 修饰符。

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

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

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

    【讨论】:

    • 谢谢..我会记住..但这对我的问题没有帮助。
    • 答案可能有两种选择。我猜是错误的选择。另一个问题是有状态的小部件。那好吧。 50/50 的机会
    猜你喜欢
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2018-11-04
    • 2020-12-03
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多