I have a list of Raised buttons, I want the background color of the selected button to change in its onPressed()
I tried changing the color in setState but it doesn't do anything.
This is the function that generates the list of Buttons
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;
}
This is where I call the function
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();
}
}
}));
}
When I press any button, its isSelected value changes but the background doesn't change accordingly
ElevatedButton
)Since RaisedButton
is now deprecated, use ElevatedButton
:
Code:
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!
),
),
),
);
}
}
It was difficult to implement your code because of undefined classes and variable, however I created a small example which will help you what you are looking for.
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;
}
Output:
Unless I'm mistaken, what you're trying to do is already handled by flutter. I think all you have to do is set the hightlightColor
of the button and when it is pressed it will change to that color. And you could set this into the theme for your entire application so that all buttons behave the same rather then setting it for each individual button.
However, there's also a reason why what you're doing isn't working. You haven't included quite enough code for me to tell, but I believe the reason why what you're doing isn't working is that you have a List of data that you're mutating when the button is pressed (i.e. zones[i].isSelected = false;
). You're doing that in a setState, but the way that flutter checks whether something needs rebuilding is by doing an equality compare on the State's members (i.e. it will check whether zones == zones).
Because 'zones' is just a list, and is actually the same list in for the old state and the new state, flutter will assume nothing has changed and won't bother rebuilding.
There's two easy ways to get around this. One would be to make a copy of the list each time it is modified and set the zones
member to that, so that when flutter does the compare old.zones != new.zones
. The other way would be to keep a separate object that you change each time the list is modified (I tend to use an integer called changeCounter that I increment each time the list changes) as that way you can 'fool' flutter into rebuilding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With