如何在 onPressed() 中动态更改凸起按钮的背景颜色
How to change the background color of raised button dynamically in onPressed()
我有一个凸起按钮列表,我希望所选按钮的背景颜色在其 onPressed() 中发生变化
我尝试在 setState 中更改颜色,但没有任何效果。
这是生成按钮列表的函数
List<Widget> _makeZoneList(List<Zone> zones) {
List<Widget>Buttons = new List();
for (int i = 0; i < zones.length; i++) {
Buttons.add(RaisedButton(
color: zones[i].isSelected ? AppColors.primaryColor : AppColors.white,
onPressed: () {
setState(() {
if (zones[i].isSelected){
zones[i].isSelected = false;
}
else{
zones[i].isSelected = true;
}
print(zones[i].isSelected.toString());
});
},
child: Text(zones.elementAt(i).text)
));
}
return Buttons;
}
这是我调用函数的地方
Widget _zoneBody() {
return Padding(
padding: EdgeInsets.all(32),
child: StreamBuilder<List<Zone>>(
stream: GetterBloc.zonesStream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return new Container();
} else {
if (snapshot.hasData) {
return Wrap(
spacing: 6.0, // gap between adjacent chips
children: _makeZoneList(snapshot.data));
} else {
return new Container();
}
}
}));
}
当我按下任何按钮时,它的 isSelected 值发生变化,但背景没有相应变化
除非我弄错了,否则你要做的事情已经由 flutter 处理了。我想你所要做的就是设置按钮的 hightlightColor
,当它被按下时它会变成那种颜色。您可以将它设置到整个应用程序的主题中,这样所有按钮的行为都相同,而不是为每个单独的按钮设置它。
但是,您的操作不起作用也是有原因的。你没有包含足够多的代码让我告诉你,但我相信你正在做的事情不起作用的原因是你有一个数据列表,当按下按钮时你正在改变这些数据(即 zones[i].isSelected = false;
).您正在 setState 中执行此操作,但是 flutter 检查是否需要重建某些内容的方式是通过对 State 的成员进行相等比较(即,它将检查区域是否 == 区域)。
因为'zones'只是一个列表,对于旧状态和新状态实际上是同一个列表,flutter会假设什么都没有改变并且不会费心重建。
有两种简单的方法可以解决这个问题。一种是每次修改列表时都复制一份列表,并将 zones
成员设置为该列表,这样当 flutter 进行比较时 old.zones != new.zones
。另一种方法是保留一个单独的对象,每次修改列表时都会更改该对象(我倾向于使用一个名为 changeCounter 的整数,每次列表更改时都会递增),这样您就可以 'fool' 开始重建.
您可以做的是在区域 class 中创建一个 "color" 属性(不需要为其设置任何值)。然后将RaisedButton
的color
属性设置为zone.color ??= AppColors.primaryColor
.
现在,在 onPressed
函数中,您可以检查是否 !zone.isSelected
然后设置 zone.color = Colors.white
.
下面是创建RaisedButton的实现。您还可以检查完整的实现 here
List<Widget> _createButton(BuildContext context, List<Zone> zones) {
return zones.map((Zone zone) {
return RaisedButton(
onPressed: () {
setState(() {
if (!zone.isSelected) {
zone.color = AppColors.white;
}
});
},
color: zone.color ??= Theme.of(context).primaryColor,
child: Text(zone.text),
);
}).toList();
}
更新答案(ElevatedButton
)
由于 RaisedButton
现已弃用,请使用 ElevatedButton
:
代码:
class _MyState extends State<MyPage> {
bool _flag = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => setState(() => _flag = !_flag),
child: Text(_flag ? 'Red' : 'Green'),
style: ElevatedButton.styleFrom(
primary: _flag ? Colors.red : Colors.teal, // This is what you need!
),
),
),
);
}
}
旧答案
由于未定义 类 和变量,很难实现您的代码,但是我创建了一个小示例,可以帮助您找到所需的内容。
List<bool> _list = [true, false, true, false];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title")),
body: ListView(children: _buildButtons()),
);
}
List<Widget> _buildButtons() {
List<Widget> listButtons = List.generate(_list.length, (i) {
return RaisedButton(
color: _list[i] ? Colors.green : Colors.red,
onPressed: () {
setState(() {
_list[i] = !_list[i];
});
},
child: Text("Button #${i}"),
);
});
return listButtons;
}
输出:
这是一个非常简单的方法。
bool isButtonPressed = false;
RaisedButton(
color: isButtonPressed ? Colors.green : Colors.red,
onPressed: () {
setState(() {
isButtonPressed =!isButtonPressed;
});
},
),
我有一个凸起按钮列表,我希望所选按钮的背景颜色在其 onPressed() 中发生变化
我尝试在 setState 中更改颜色,但没有任何效果。
这是生成按钮列表的函数
List<Widget> _makeZoneList(List<Zone> zones) {
List<Widget>Buttons = new List();
for (int i = 0; i < zones.length; i++) {
Buttons.add(RaisedButton(
color: zones[i].isSelected ? AppColors.primaryColor : AppColors.white,
onPressed: () {
setState(() {
if (zones[i].isSelected){
zones[i].isSelected = false;
}
else{
zones[i].isSelected = true;
}
print(zones[i].isSelected.toString());
});
},
child: Text(zones.elementAt(i).text)
));
}
return Buttons;
}
这是我调用函数的地方
Widget _zoneBody() {
return Padding(
padding: EdgeInsets.all(32),
child: StreamBuilder<List<Zone>>(
stream: GetterBloc.zonesStream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return new Container();
} else {
if (snapshot.hasData) {
return Wrap(
spacing: 6.0, // gap between adjacent chips
children: _makeZoneList(snapshot.data));
} else {
return new Container();
}
}
}));
}
当我按下任何按钮时,它的 isSelected 值发生变化,但背景没有相应变化
除非我弄错了,否则你要做的事情已经由 flutter 处理了。我想你所要做的就是设置按钮的 hightlightColor
,当它被按下时它会变成那种颜色。您可以将它设置到整个应用程序的主题中,这样所有按钮的行为都相同,而不是为每个单独的按钮设置它。
但是,您的操作不起作用也是有原因的。你没有包含足够多的代码让我告诉你,但我相信你正在做的事情不起作用的原因是你有一个数据列表,当按下按钮时你正在改变这些数据(即 zones[i].isSelected = false;
).您正在 setState 中执行此操作,但是 flutter 检查是否需要重建某些内容的方式是通过对 State 的成员进行相等比较(即,它将检查区域是否 == 区域)。
因为'zones'只是一个列表,对于旧状态和新状态实际上是同一个列表,flutter会假设什么都没有改变并且不会费心重建。
有两种简单的方法可以解决这个问题。一种是每次修改列表时都复制一份列表,并将 zones
成员设置为该列表,这样当 flutter 进行比较时 old.zones != new.zones
。另一种方法是保留一个单独的对象,每次修改列表时都会更改该对象(我倾向于使用一个名为 changeCounter 的整数,每次列表更改时都会递增),这样您就可以 'fool' 开始重建.
您可以做的是在区域 class 中创建一个 "color" 属性(不需要为其设置任何值)。然后将RaisedButton
的color
属性设置为zone.color ??= AppColors.primaryColor
.
现在,在 onPressed
函数中,您可以检查是否 !zone.isSelected
然后设置 zone.color = Colors.white
.
下面是创建RaisedButton的实现。您还可以检查完整的实现 here
List<Widget> _createButton(BuildContext context, List<Zone> zones) {
return zones.map((Zone zone) {
return RaisedButton(
onPressed: () {
setState(() {
if (!zone.isSelected) {
zone.color = AppColors.white;
}
});
},
color: zone.color ??= Theme.of(context).primaryColor,
child: Text(zone.text),
);
}).toList();
}
更新答案(ElevatedButton
)
由于 RaisedButton
现已弃用,请使用 ElevatedButton
:
代码:
class _MyState extends State<MyPage> {
bool _flag = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => setState(() => _flag = !_flag),
child: Text(_flag ? 'Red' : 'Green'),
style: ElevatedButton.styleFrom(
primary: _flag ? Colors.red : Colors.teal, // This is what you need!
),
),
),
);
}
}
旧答案
由于未定义 类 和变量,很难实现您的代码,但是我创建了一个小示例,可以帮助您找到所需的内容。
List<bool> _list = [true, false, true, false];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Title")),
body: ListView(children: _buildButtons()),
);
}
List<Widget> _buildButtons() {
List<Widget> listButtons = List.generate(_list.length, (i) {
return RaisedButton(
color: _list[i] ? Colors.green : Colors.red,
onPressed: () {
setState(() {
_list[i] = !_list[i];
});
},
child: Text("Button #${i}"),
);
});
return listButtons;
}
输出:
这是一个非常简单的方法。
bool isButtonPressed = false;
RaisedButton(
color: isButtonPressed ? Colors.green : Colors.red,
onPressed: () {
setState(() {
isButtonPressed =!isButtonPressed;
});
},
),