web-dev-qa-db-fra.com

Comment changer dynamiquement la couleur d'arrière-plan du bouton en relief dans onPressed ()

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

3
Ghada Shebl

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:

enter image description here

4
CopsOnRoad

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.

2
rmtmckenzie

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();
  }
1
Ankit