J'ai une liste de boutons surélevés, je veux que la couleur d'arrière-plan du bouton sélectionné change dans son onPressed ()
J'ai essayé de changer la couleur dans setState mais cela ne fait rien.
C'est la fonction qui génère la liste des boutons
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;
}
C'est là que j'appelle la fonction
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();
}
}
}));
}
Lorsque j'appuie sur un bouton, sa valeur isSelected change mais l'arrière-plan ne change pas en conséquence
Il était difficile d'implémenter votre code en raison de classes et de variables non définies, cependant j'ai créé un petit exemple qui vous aidera dans ce que vous recherchez.
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;
}
Production:
Sauf erreur, ce que vous essayez de faire est déjà géré par le flottement. Je pense que tout ce que vous avez à faire est de régler le hightlightColor
du bouton et quand il est enfoncé, il changera de cette couleur. Et vous pouvez définir cela dans le thème de votre application entière afin que tous les boutons se comportent de la même manière plutôt que de le définir pour chaque bouton individuel.
Cependant, il y a aussi une raison pour laquelle ce que vous faites ne fonctionne pas. Vous n'avez pas inclus assez de code pour que je puisse le dire, mais je pense que la raison pour laquelle ce que vous faites ne fonctionne pas est que vous avez une liste de données que vous mutez lorsque vous appuyez sur le bouton (c'est-à-dire zones[i].isSelected = false;
). Vous faites cela dans un setState, mais la façon dont le flottement vérifie si quelque chose doit être reconstruit consiste à faire une comparaison d'égalité sur les membres de l'État (c'est-à-dire qu'il vérifiera si zones == zones).
Parce que "zones" n'est qu'une liste, et est en fait la même liste pour l'ancien et le nouvel état, flutter supposera que rien n'a changé et ne dérangera pas la reconstruction.
Il existe deux façons simples de contourner ce problème. L'une consiste à faire une copie de la liste à chaque modification et à définir le membre zones
sur celui-ci, de sorte que lorsque flutter effectue la comparaison old.zones != new.zones
. L'autre façon serait de conserver un objet séparé que vous changez chaque fois que la liste est modifiée (j'ai tendance à utiliser un entier appelé changeCounter que j'incrémente à chaque fois que la liste change) car de cette façon, vous pouvez `` tromper '' le flottement dans la reconstruction.
Ce que vous pouvez faire est de créer une propriété "couleur" (non requise pour définir une valeur) dans la classe Zone. Définissez ensuite la propriété color
de RaisedButton
sur zone.color ??= AppColors.primaryColor
.
Et maintenant, à l'intérieur de la fonction onPressed
, vous pouvez vérifier si !zone.isSelected
puis définissez zone.color = Colors.white
.
Vous trouverez ci-dessous l'implémentation de la création de RaisedButton. Vous pouvez également vérifier la mise en œuvre complète ici
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();
}