【问题标题】:Override widget style in Flutter在 Flutter 中覆盖小部件样式
【发布时间】:2019-05-08 19:09:21
【问题描述】:

问题:如何以某种方式自动(如果可能)为我的应用程序中的所有RaisedButton 小部件设置样式?


我正在将一个应用从原生 Android 转换为 Flutter。在这个应用程序中,所有主要的操作按钮都是圆形的、灰色的,并且有一个白色的边框。在 Android 中,这就像在 styles.xml 中定义样式并设置 <Button style="MyPrimaryButton"/> 一样简单。

另一方面,在 Flutter 中,我只能找到使用 property: Theme.of(context).property 设置单个属性的示例(包括来自 theming docs 的示例),并且似乎没有其他方法可以传递样式属性颜色和字体。

以下是我想为所有RaisedButton 小部件使用的样式:

RaisedButton(
  color: Theme.of(context).accentColor,
  elevation: 0,
  shape: new RoundedRectangleBorder(
    side: BorderSide(color: Colors.white, width: 1.0, style: BorderStyle.solid),
    borderRadius: new BorderRadius.circular(30)),
)

这个purportedly similar question 主要基于意见而关闭,但我不是在征求您的意见。我在问是否有 一种方法来设置这些按钮的样式,最好不要像接受的答案所建议的那样将小部件源代码复制粘贴到我自己的类中(尽管这仍然是唯一的方法这样做很可能就是答案)。

【问题讨论】:

  • 为什么不在 MaterialApp 主题级别设置按钮主题?
  • 我想我不清楚主题是如何工作的,但由于 Hemanth 提供的答案,我更好地理解了它,现在看看它是如何使用的。
  • 谢谢。当我浏览重复项时,我没有看到那个;我的错。

标签: flutter themes


【解决方案1】:

您实际上可以通过扩展RaisedButton 类并覆盖您需要的默认属性来实现它。

例子:

class Sample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: MyButton(onClicked: () => null,child: Text('Sample'),),
      ),
    );
  }
}

class MyButton extends RaisedButton {
  const MyButton({@required this.onClicked, this.child})
      : super(onPressed: onClicked, elevation: 0.0, child: child);

  final VoidCallback onClicked;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Theme(
      data: Theme.of(context).copyWith(
        buttonColor: Theme.of(context).accentColor,
        buttonTheme: Theme.of(context).buttonTheme.copyWith(
              shape: RoundedRectangleBorder(
                side: const BorderSide(
                  color: Colors.white,
                  width: 1.0,
                  style: BorderStyle.solid,
                ),
                borderRadius: BorderRadius.circular(30),
              ),
            ),
      ),
      child: Builder(builder: super.build),
    );
  }
}

MyButton 可以在任何你想要的地方使用 RaisedButton 与你的风格。

希望这会有所帮助!

【讨论】:

  • 啊,好吧,我找错地方了;现在试一试。查看代码,是否有原因 elevation 包含在对 super 的调用中,而不是包含在具有其他属性的 build 方法中?只是好奇。
  • 是的,我将属性传递给超类。这很重要,您可以看到我正在重用超类的build 方法。
【解决方案2】:

您可以提取您已有的customized widget,然后使用它everywhere

这里有 03 种可能性:

Local VariableWidgetMethod 一样使用它。

1- 局部变量
代码:

var raisedButton = RaisedButton(
      color: Theme.of(context).accentColor,
      elevation: 0,
      shape: new RoundedRectangleBorder(
          side: BorderSide(
              color: Colors.white, width: 1.0, style: BorderStyle.solid),
          borderRadius: new BorderRadius.circular(30)),
      onPressed: null,
    );

用法:

Container(child: raisedButton),

2-方法

代码:

RaisedButton buildRaisedButton(BuildContext context) {
    return RaisedButton(
          color: Theme.of(context).accentColor,
          elevation: 0,
          shape: new RoundedRectangleBorder(
              side: BorderSide(
                  color: Colors.white, width: 1.0, style: BorderStyle.solid),
              borderRadius: new BorderRadius.circular(30)),
          onPressed: null,
        );
  }

用途:

Container(child: buildRaisedButton(context)),

3- 小部件

代码:

 class MyRaisedButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
            color: Theme.of(context).accentColor,
            elevation: 0,
            shape: new RoundedRectangleBorder(
      side: BorderSide(
          color: Colors.white, width: 1.0, style: BorderStyle.solid),
      borderRadius: new BorderRadius.circular(30)),
            onPressed: null,
          );
  }
}

用途:

Container( child: MyRaisedButton()),

请注意,您可以通过单击小部件并执行 (ctrl +) 来快速完成。

结果将是:

【讨论】:

    【解决方案3】:

    尝试将您的小部件用作变量或方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      相关资源
      最近更新 更多