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

Posted

技术标签:

【中文标题】如何在 onPressed() 中动态更改凸起按钮的背景颜色【英文标题】:How to change the background color of raised button dynamically in onPressed() 【发布时间】:2019-09-01 11:24:17 【问题描述】:

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

【问题讨论】:

感谢您的快速回复.. 不幸的是它现在仍在工作.. 我认为问题是我的小部件在列表中.. 你可以使用这个解决方案:***.com/a/61526932/865249 【参考方案1】:

更新答案 (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(
            primary: _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属性。【参考方案2】:

除非我弄错了,否则您尝试做的事情已经被颤振处理了。我想你所要做的就是设置按钮的hightlightColor,当它被按下时它会变成那个颜色。您可以将其设置为整个应用程序的主题,以便所有按钮的行为相同,而不是为每个单独的按钮设置它。

但是,您正在做的事情不起作用也是有原因的。你没有包含足够多的代码让我告诉你,但我相信你所做的事情不起作用的原因是你有一个数据列表,当你按下按钮时你正在变异(即@987654323 @)。您在 setState 中执行此操作,但颤振检查是否需要重建的方式是对 State 的成员进行相等比较(即它将检查区域是否 == 区域)。

因为 'zones' 只是一个列表,实际上旧状态和新状态的列表是相同的,所以 Flutter 会假设没有任何变化并且不会打扰重建。

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

【讨论】:

【参考方案3】:

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

bool isButtonPressed = false;

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

【讨论】:

【参考方案4】:

您可以做的是在 Zone 类中创建一个“颜色”属性(不需要为其设置任何值)。然后将RaisedButtoncolor属性设置为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();
  

【讨论】:

以上是关于如何在 onPressed() 中动态更改凸起按钮的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

Flutter中常用的按钮组件-RaisedButton(凸起的按钮)

Flutter中常用的按钮组件-RaisedButton(凸起的按钮)

Flutter——WidgetButton

Flutter——WidgetButton

Android 底部导航栏中间凸起动态配置替换底部导航栏Tab图标(按钮标签)的实现方案

如何在网格视图下方添加“凸起按钮”?