setState 不会在 flutter 中更改 gridview 中的值
setState not changing value in gridview in flutter
基本上我正在更新 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 型号:
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} ];
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
If you never intend to change a variable, use final or const, either
instead of var or in addition to a type. A final variable can be set
only once; a const variable is a compile-time constant. (Const
variables are implicitly final.) A final top-level or class variable
is initialized the first time it’s used.
我的回答基于以下事实:您将 list[i]["selected"]
作为地图访问,同时将 Grades
定义为对象。
您的 class 必须扩展 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
}
}
我遇到了同样的问题。我的解决方案是在 GridView 中重构你想要改变的对象。不要更新列表中的项目,而是重建列表并根据需要更新项目。也许有用。
我猜如果list的point不改变,包含它的GridView就不会改变
基本上我正在更新 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 型号:
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} ];
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
If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.
我的回答基于以下事实:您将 list[i]["selected"]
作为地图访问,同时将 Grades
定义为对象。
您的 class 必须扩展 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
}
}
我遇到了同样的问题。我的解决方案是在 GridView 中重构你想要改变的对象。不要更新列表中的项目,而是重建列表并根据需要更新项目。也许有用。
我猜如果list的point不改变,包含它的GridView就不会改变