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

时间:2019-04-10 22:19:00

标签: flutter flutter-layout setstate flutter-sliver

我有一个“凸起”按钮列表,我希望所选按钮的背景颜色在其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值会更改,但背景不会相应更改

4 个答案:

答案 0 :(得分:1)

这是一个非常简单的方法。

bool isButtonPressed = false;

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

答案 1 :(得分:0)

除非我弄错了,否则您正在尝试做的事情已经由抖动处理了。我认为您所要做的就是设置按钮的hightlightColor,当按下按钮时它将变为该颜色。您可以将其设置为整个应用程序的主题,以使所有按钮的行为相同,而不必为每个按钮进行设置。

但是,还有一个原因导致您的工作无法正常进行。您没有提供足够多的代码让我知道,但是我相信您正在执行的操作无法正常工作的原因是,您拥有按下按钮时正在突变的数据列表(即{{ 1}})。您是在setState中执行此操作的,但是flutter检查是否需要重建某些内容的方法是通过对State的成员进行相等比较(即,它将检查是否为zone == zone)。

因为“区域”只是一个列表,并且实际上是旧状态和新状态中的相同列表,所以抖动将假定没有任何变化并且不会打扰重建。

有两种简单的方法可以解决此问题。一种方法是在每次修改列表时复制该列表,并将zones[i].isSelected = false;成员设置为该成员,以便在抖动时进行比较zones。另一种方法是保留一个单独的对象,该对象在每次修改列表时都会更改(我倾向于使用一个名为changeCounter的整数,每次列表更改时我都会递增),这样您就可以“愚弄”重建。 / p>

答案 2 :(得分:0)

您可以做的是在Zone类中创建一个“颜色”属性(不需要为其设置任何值)。然后将color的{​​{1}}属性设置为RaisedButton

现在,在zone.color ??= AppColors.primaryColor函数中,您可以检查onPressed是否设置了!zone.isSelected

下面是创建RaisedButton的实现。您还可以检查完整的实现here

zone.color = Colors.white

答案 3 :(得分:0)

由于未定义的类和变量,很难实现您的代码,但是我创建了一个小示例,它将为您提供所需的帮助。

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