web-dev-qa-db-ja.com

発生したボタンの背景色を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の値は変わりますが、背景はそれに応じて変わりません

3
Ghada Shebl

未定義のクラスと変数のためにコードを実装することは困難でしたが、私はあなたが探しているものを手助けする小さな例を作成しました。

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;
}

出力:

enter image description here

4
CopsOnRoad

私が間違えない限り、あなたがやろうとしていることはすでに羽ばたきによって処理されています。ボタンの hightlightColor を設定するだけで、ボタンを押すとその色に変わります。そして、これをアプリケーション全体のテーマに設定して、個々のボタンごとに設定するのではなく、すべてのボタンが同じように動作するようにすることができます。

しかし、あなたがやっていることがうまくいかない理由もあります。十分なコードが含まれていませんが、ボタンが押されたときに変化するデータのリストがあるためです(zones[i].isSelected = false;)。あなたはそれをsetStateで行っていますが、フラッターが何かを再構築する必要があるかどうかを確認する方法は、状態のメンバーで等価比較を行うことです(つまり、ゾーン==ゾーンかどうかを確認します)。

「ゾーン」は単なるリストであり、実際には古い状態と新しい状態で同じリストであるため、フラッターは何も変更されていないと想定し、再構築を気にしません。

これを回避する簡単な方法が2つあります。 1つは、リストが変更されるたびにリストのコピーを作成し、zonesメンバーをそれに設定して、フラッターが比較を行うときにold.zones != new.zones。もう1つの方法は、リストが変更されるたびに変更する個別のオブジェクトを保持することです(リストを変更するたびにインクリメントするchangeCounterと呼ばれる整数を使用する傾向があります)。その方法で、ばたつくことができ、再構築に失敗します。

2
rmtmckenzie

あなたができることは、Zoneクラスに "color"プロパティ(値を設定する必要はありません)を作成することです。次に、colorRaisedButtonプロパティをzone.color ??= AppColors.primaryColorに設定します。

そして今、onPressed関数内で、!zone.isSelectedzone.color = Colors.whiteに設定されているかどうかを確認できます。

以下は、RaisedButtonを作成するための実装です。完全な実装を確認することもできます ここ

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