在未来的 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);
}
也许有一天它会对某人有所帮助!
我在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);
}
也许有一天它会对某人有所帮助!