如何从函数中更改 Flutter 中高架按钮的背景颜色?

Posted

技术标签:

【中文标题】如何从函数中更改 Flutter 中高架按钮的背景颜色?【英文标题】:How to change background color of Elevated Button in Flutter from function? 【发布时间】:2021-06-24 08:36:30 【问题描述】:

我是 Flutter 的新手,我上周开始使用 Flutter,现在我想做一个简单的 Xylophone 应用程序。我成功创建了用户界面并创建了一个函数playSound(int soundNumber),但是当我调用这个函数播放声音时,它给了我这个错误。

**The following _TypeError was thrown building Body(dirty, state: _BodyState#051c2):
type '_MaterialStatePropertyAll<dynamic>' is not a subtype of type 'MaterialStateProperty<Color?>?'**

这是我为playSound(int soundNumber) 函数编写的代码。

void playSound(int soundNumber) 
final player = AudioCache();
player.play('note$soundNumber.wav');

Expanded buildPlayButton(MaterialStateProperty color, int soundNumber)
return Expanded(
  child: ElevatedButton(
    onPressed: () 
      playSound(soundNumber);
    ,
    style: ButtonStyle(
      backgroundColor: color,
    ),
  ),
);

这里是我调用这个函数的地方。

Widget build(BuildContext context) 
return Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: <Widget>[
    buildPlayButton(color: MaterialStateProperty.all(Colors.red), soundNumber: 1),
    buildPlayButton(color: MaterialStateProperty.all(Colors.orangeAccent), soundNumber: 2),
    buildPlayButton(color: MaterialStateProperty.all(Colors.yellow), soundNumber: 3),
    buildPlayButton(color: MaterialStateProperty.all(Colors.indigo), soundNumber: 4),
    buildPlayButton(color: MaterialStateProperty.all(Colors.blue), soundNumber: 5),
    buildPlayButton(color: MaterialStateProperty.all(Colors.lightGreenAccent), soundNumber: 6),
    buildPlayButton(color: MaterialStateProperty.all(Colors.green), soundNumber: 7),
  ],
);

如何调用这个函数,因为它给了我上面提到的错误?

【问题讨论】:

【参考方案1】:

将颜色作为参数传递并使用 MaterialStateProperty.all(color) 来指定颜色。

buildPlayButton(color: Colors.red, soundNumber: 1)
Expanded buildPlayButton(Color color, int soundNumber)
return Expanded(
  child: ElevatedButton(
    onPressed: () 
      playSound(soundNumber);
    ,
    style: ButtonStyle(
      backgroundColor: MaterialStateProperty.all<Color>(color),
    ),
  ),
);

示例按钮

一般情况

ElevatedButton(
  style: ElevatedButton.styleFrom(
    primary: Colors.red, // background
    onPrimary: Colors.yellow, // foreground
  ),
  onPressed: () ,
  child: Text('ElevatedButton with custom foreground/background'),
)

示例按钮

参考:

ElevatedButton class

【讨论】:

在函数中添加这个参数时我必须传递哪些参数? 我已经更新了帖子。将颜色作为参数传递并使用 MaterialStateProperty.all(color) 指定颜色。 感谢@hbamithkumara ...它就像一个魅力...【参考方案2】:
ElevatedButton(onPressed: resetHandler,
               child: Text("button"),
               style: ElevatedButton.styleFrom(primary: Colors.amber),),

【讨论】:

style:Elevatedbutton.styleFrom(primary:Colors.amber)【参考方案3】:

您可以使用 styleFrom 静态方法或 ButtonStyle 类来设置 ElevatedButton 的样式。第一个比第二个更方便。

使用 styleFrom 设置 ElevatedButton 的样式:

ElevatedButton(
      child: Text('Button'),
      onPressed: () ,
      style: ElevatedButton.styleFrom(
           Color primary, // set the background color 
           Color onPrimary, 
           Color onSurface, 
           Color shadowColor, 
           double elevation, 
           TextStyle textStyle, 
           EdgeInsetsGeometry padding, 
           Size minimumSize, 
           BorderSide side, 
           OutlinedBorder shape, 
           MouseCursor enabledMouseCursor, 
           MouseCursor disabledMouseCursor, 
           VisualDensity visualDensity, 
           MaterialTapTargetSize tapTargetSize, 
           Duration animationDuration, 
           bool enableFeedback
     ),
),

示例:

ElevatedButton(
            child: Text('Button'),
            onPressed: () ,
            style: ElevatedButton.styleFrom(
                primary: Colors.purple,
                padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20),
                textStyle: TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.bold)),
),

使用 ButtonStyle 设置 ElevatedButton 样式:

style: ButtonStyle(
  MaterialStateProperty<TextStyle> textStyle,    
  MaterialStateProperty<Color> backgroundColor,   
  MaterialStateProperty<Color> foregroundColor, 
  MaterialStateProperty<Color> overlayColor, 
  MaterialStateProperty<Color> shadowColor, 
  MaterialStateProperty<double> elevation, 
  MaterialStateProperty<EdgeInsetsGeometry> padding, 
  MaterialStateProperty<Size> minimumSize, 
  MaterialStateProperty<BorderSide> side, 
  MaterialStateProperty<OutlinedBorder> shape, 
  MaterialStateProperty<MouseCursor> mouseCursor,    
  VisualDensity visualDensity, 
  MaterialTapTargetSize tapTargetSize, 
  Duration animationDuration, 
  bool enableFeedback
)

示例

ElevatedButton(
            child: Text('Button'),
            onPressed: () ,
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.red),
                padding: MaterialStateProperty.all(EdgeInsets.all(50)),
                textStyle: MaterialStateProperty.all(TextStyle(fontSize: 30))),
),

【讨论】:

感谢您的回答,但我不明白为什么我不能做 Theme.of(context).elevatedButtonTheme.copyWith(backgroundColor: ...) 提升按钮主题在运行时为空。我不明白为什么,因为其他主题不为空......【参考方案4】:
style: ButtonStyle(  
  MaterialStateProperty.all(backgroundColor),   
),

同样,您可以将MaterialStateProperty.all(&lt;Value here&gt;) 添加到提升按钮的大多数属性(高度、填充、边框等)。

【讨论】:

【参考方案5】:
style: ElevatedButton.styleFrom(Primary : Colors.black),

【讨论】:

【参考方案6】:

截图:


代码:

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!
          ),
        ),
      ),
    );
  

【讨论】:

【参考方案7】:
ElevatedButton(
          onPressed: (),
          child: Text('comprar'),
          style: ElevatedButton.styleFrom(
            primary: Theme.of(context).primaryColor
          )
        )

【讨论】:

欢迎来到 Stack Overflow!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。【参考方案8】:

确保添加 onPressed: () ,

否则颜色会变灰

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案9】:

您有 3 个选项来更改背景颜色:

ElevatedButton.styleFrom : 如果您只想更改背景颜色和前景色而不考虑状态,那么您可以按照以下方式进行操作。

ElevatedButton(
  style: ElevatedButton.styleFrom(
    primary: Colors.red, // background
    onPrimary: Colors.white, // foreground
  ),
  onPressed: ()  ,
  child: Text('custom foreground/background'),
)

MaterialStateProperty.all: 覆盖所有状态的 ElevatedButtons 默认背景(文本/图标)颜色。

 ElevatedButton(style:   
    ButtonStyle(
      backgroundColor: MaterialStateProperty.all(Colors.red),
    onPressed: ()  ,
    child: Text('custom foreground/background'),
    ));

MaterialStateProperty.resolveWith : 默认情况下,提升按钮继承蓝色。我们可以使用 style 参数和 ButtonStyle 类调整默认样式。 按钮具有不同的状态,例如按下、禁用、悬停等。您可以更改每种状态的样式。在下面的sn-p中,按钮按下时默认颜色变为绿色。

ElevatedButton(
  style: ButtonStyle(
    backgroundColor: MaterialStateProperty.resolveWith<Color>(
      (Set<MaterialState> states) 
        if (states.contains(MaterialState.pressed))
          return Colors.green;
        return null; // Use the component's default.
      ,
    ),
  ),
)

【讨论】:

以上是关于如何从函数中更改 Flutter 中高架按钮的背景颜色?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:更改 ListView.builder 中选定按钮的背景颜色

如何在颤动中更改文本按钮颜色?

如何更改MFC按钮的背景色

UIButton 背景图像从另一个按钮更改

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

如何在 Flutter 中选择时更改 ListTile 的背景颜色