在未来的 gridView 中更改按钮颜色和图标

Change button color and icon in future gridView

我在Future Builder中有一个gridview,我想要这种渲染。 As you can see, when an element is selected, the color change, the icon too and obviously I add it to a Set (to have only single element)

标题来自 API 调用。

所以我做了这样的事情:

FutureBuilder<List<ProjectTheme>> (
 future: themeColorList.buildTheme(),
 builder: (BuildContext context, AsyncSnapshot<List<ProjectTheme>> snapshot) {
   if(snapshot.hasData)
     return GridView.builder(
       itemCount: themes.length,
       gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
       itemBuilder: (BuildContext context, int index) {
         var theme = snapshot.data[index];
           return Stack(
              children: <Widget>[
                 Positioned(
                   child: ButtonTheme(
                   height: height * 0.15,
                   minWidth: width * 0.4,
                   child: RaisedButton(
                     shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(5.0)),
                        color: selectedThemes.contains(theme.themeName) ? theme.themeColor = Colors.grey : theme.themeColor = theme.themeColor,
                        onPressed: () {
                          setState(() {
                            changeOneClickItemState(theme);
                          });
                        },
                     ),
                   ),
                 ),
                 Padding(
                   child: Align(
                     alignment: Alignment.center,
                     child: selectedThemes.contains(theme.themeName)? Icon(Icons.check):theme.themeIcon,
                   )
                 ),
              ],
            );
          }
        );
      }
  )

selectedThemes 就是我添加选择的列表。

这是在 onPressed 按钮中调用的方法:

 void changeOneClickItemState(ProjectTheme theme) {
    pressed = !pressed;
    pressed ? selectedThemes.add(theme.themeName) : selectedThemes.remove(theme.themeName);
 }

所以它工作得差不多,但我需要在每个元素上点击几次才能看到选中的元素。似乎该应用程序不是反应性的,我认为这是因为需要时间来检查元素是否在列表中。 事实上,我无法在我的 RaisedButton 的颜色 属性 中设置 "pressed ?" 而不是 "selectedTheme.contains(theme.themeName)",因为我所有的按钮都变成灰色。但我需要让它更具反应性,因为客户不能接受多次点击按钮以使其工作...

你知道我该如何解决这个问题吗?

太棒了,我终于找到方法了。 正如我所说,问题是 gridView 是在 Future Builder 中构建的。

所以,我创建了一个构建主题的方法,并在 init 中调用它。

List<ProjectTheme> projectThemes;

void initState() {
  super.initState();
  getThemes();
  buildThemes();
}

Future<List<ProjectTheme>> buildThemes() async {
  List<ProjectTheme> projectThemeList = await themeColorList.buildTheme();
  setState(() {
    this.projectThemes = projectThemeList;
  });

  return projectThemeList;
}

然后在我的 class 中添加 属性 "isPressed" 后,我构建了如下所示的网格视图:

GridView.builder(
  itemCount: themes != null ? themes.length : 0,
  gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemBuilder: (BuildContext context, int index) {
      var theme = projectThemes[index];
      theme.isPressed = false;

      return projectThemes != null ? Stack(
           children: <Widget>[
              Positioned(
                child: ButtonTheme(
                   height: height * 0.15,
                   minWidth: width * 0.4,
                   child: RaisedButton.icon(
                   shape: RoundedRectangleBorder(
                   borderRadius: BorderRadius.circular(5.0)),

                   onPressed: () {
                     setState(() {
                       selectedThemes.contains(theme.themeName) ?
                       theme.isPressed = false :
                       theme.isPressed = true;

                       changeOneClickItemState(theme);
                     });
                   },
                   color: selectedThemes.contains(theme.themeName) ? Colors.grey : theme.themeColor,
                   icon: selectedThemes.contains(theme.themeName) ? Icon(Icons.check) : theme.themeIcon,
                   label: Text(''),
                 ),
                ),
              ),
            ],
          ) : Container(child: Center(child: CircularProgressIndicator()));
         }
       )

并更改 OneClickItemState :

 void changeOneClickItemState(ProjectTheme theme) {
   theme.isPressed ? 
   selectedThemes.add(theme.themeName) : 
   selectedThemes.remove(theme.themeName);
 }

也许有一天它会对某人有所帮助!