如何在onPressed()中动态更改按钮的背景颜色

20

我有一个Raised button列表,我希望在其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值会发生改变,但背景不会相应地改变。

谢谢您的快速回复。不幸的是,它仍然没有起作用。我认为问题在于我的小部件在列表中。 - Ghada Shebl
您可以使用此解决方案:https://dev59.com/g1UL5IYBdhLWcg3wFEvw#61526932 - Ricardo
4个回答

43

更新的答案 (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(
            backgroundColor: _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;
}

输出:

输入图像描述


记得设置 onPressed 属性。 - Adam Smaka

2
除非我弄错了,你正在尝试做的事情已经被Flutter处理了。我认为你所要做的就是设置按钮的highlightColor,当它被按下时,它会变成该颜色。而且你可以将其设置为整个应用程序的主题,这样所有的按钮都会有相同的行为,而不是为每个单独的按钮设置它。
然而,你做的事情还没生效也有一个原因。你没有提供足够的代码让我判断,但我相信你现在所做的事情没有成功是因为你有一个数据列表,在按钮被按下时进行修改(即zones[i].isSelected = false;)。你在一个setState中进行了这个操作,但Flutter检查是否需要重建的方式是通过对State成员进行相等比较来实现的(即它会检查zones == zones)。
因为'zones'只是一个列表,并且在旧状态和新状态中实际上是相同的列表,Flutter会认为没有什么改变,就不会重新构建。
有两种简单的方法可以解决这个问题。一种方法是每次修改列表时都复制一份,并将zones成员设置为该副本,这样当Flutter进行比较old.zones != new.zones时就会生效。另一种方法是保持一个单独的对象,每次修改列表时都更改它(我倾向于使用一个称为changeCounter的整数,每次列表更改时增加它),这样你就可以“欺骗”Flutter进行重建。

2
这里有一个非常简单的方法。
bool isButtonPressed = false;

RaisedButton(
            color: isButtonPressed ? Colors.green : Colors.red,
            onPressed: () {
              setState(() {
                isButtonPressed =!isButtonPressed;
              });
            },
          ),

1
你可以在Zone类中创建一个“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();
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接