当前位置:   article > 正文

Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解_flutter buttonstyle

flutter buttonstyle

Flutter 中的 ButtonStyle 和 MaterialStateProperty 是在 Flutter 2.0 发布时引入的。在 Flutter 1 中,我们可以通过设置 textColor、backgroundColor 等参数来快速配置按钮的样式。但是在 Flutter 2 中,这些参数被废弃了,取而代之的是 ButtonStyle。ButtonStyle 可以通过 MaterialStateProperty 来支持不同平台下的交互状态展示。本文将深入探讨这两个新特性。

1.MaterialStateProperty

MaterialStateProperty 的设计理念基于 Material Design 去针对全平台的交互进行兼容。在 MaterialStateProperty 体系中,有一个 MaterialState 枚举,它包含了多种不同的状态,例如 disabled、hovered、focused、selected、pressed、dragged、error 等。MaterialStateProperty 可以通过这些状态来控制控件的样式。

举个例子,假设我们需要在按钮悬停时修改按钮的背景颜色。在Flutter 1 中,我们可以这样写:

  1. FlatButton(
  2. onPressed: () {},
  3. color: Colors.blue,
  4. hoverColor: Colors.green,
  5. child: Text('Button'),
  6. )

但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:

  1. TextButton(
  2. onPressed: () {},
  3. style: ButtonStyle(
  4. backgroundColor: MaterialStateProperty.resolveWith((states) {
  5. if (states.contains(MaterialState.hovered)) {
  6. return Colors.green;
  7. }
  8. return Colors.blue;
  9. }),
  10. ),
  11. child: Text('Button'),
  12. )

在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的背景颜色,这样就可以轻松地实现不同状态下的样式切换。在这个例子中,我们使用 MaterialState.hovered 来处理按钮悬停时的样式。

需要注意的是,MaterialStateProperty 不仅适用于按钮,还适用于其他控件,例如 Checkbox、Radio、Slider 等。

2.ButtonStyle

ButtonStyle 是 Flutter 中一种全新的样式定义方式,它用于定义控件的样式。ButtonStyle 的设计目的是为了在不同平台下提供一致的外观和行为。例如,当用户在不同的操作系统上运行应用程序时,ButtonStyle 可以确保按钮的样式和行为都是一致的。

ButtonStyle 由多个 MaterialStateProperty 组成,每个 MaterialStateProperty 对应一个控件状态。我们可以使用 MaterialStateProperty 来定义控件不同状态下的样式。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在不同状态下的背景颜色、前景色、字体大小等。

举个例子,假设我们需要创建一个带有自定义样式的按钮。在Flutter 1 中,我们可以这样写:

  1. FlatButton(
  2. onPressed: () {},
  3. color: Colors.blue,
  4. textColor: Colors.white,
  5. child: Text('Button'),
  6. )

但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:

  1. TextButton(
  2. onPressed: () {},
  3. style: ButtonStyle(
  4. backgroundColor: MaterialStateProperty.all(Colors.blue),
  5. foregroundColor: MaterialStateProperty.all(Colors.white),
  6. textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
  7. ),
  8. child: Text('Button'),
  9. )

在上述代码中,我们使用MaterialStateProperty.all 方法来设置按钮的背景颜色、前景色和字体大小。MaterialStateProperty.all 方法可以将一个值应用到所有的状态中。

需要注意的是,ButtonStyle 的属性有很多,例如 elevation、padding、shape 等等。我们可以使用 MaterialStateProperty 来设置每个属性在不同状态下的值。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在悬停状态下的阴影。

  1. TextButton(
  2. onPressed: () {},
  3. style: ButtonStyle(
  4. elevation: MaterialStateProperty.resolveWith((states) {
  5. if (states.contains(MaterialState.hovered)) {
  6. return 10.0;
  7. }
  8. return 5.0;
  9. }),
  10. ),
  11. child: Text('Button'),
  12. )

在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的阴影。当按钮处于悬停状态时,我们将阴影的值设置为 10.0,否则设置为 5.0。

3.Theme

如果你希望在全局范围内应用某个样式,可以使用Flutter 中的 Theme。Theme 可以用来定义全局主题,包括文本样式、颜色、字体、按钮样式等等。在 ButtonStyle 中,我们也可以使用 Theme 来定义全局按钮样式。

举个例子,假设我们需要在全局范围内应用自定义按钮样式。我们可以这样写:

  1. Theme(
  2. data: ThemeData(
  3. textButtonTheme: TextButtonThemeData(
  4. style: ButtonStyle(
  5. backgroundColor: MaterialStateProperty.all(Colors.blue),
  6. foregroundColor: MaterialStateProperty.all(Colors.white),
  7. textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
  8. ),
  9. ),
  10. ),
  11. child: TextButton(
  12. onPressed: () {},
  13. child: Text('Button'),
  14. ),
  15. )

在上述代码中,我们使用Theme 来定义全局的按钮样式。我们将 ButtonStyle 定义在 textButtonTheme 中,并将其应用到 TextButton 中。

4.在Flutter 中,ButtonStyle 和 MaterialStateProperty 为我们提供了一种更加灵活、可定制的方式来定义控件样式。ButtonStyle 和 MaterialStateProperty 可以帮助我们实现不同状态下的样式切换,并支持不同平台下的交互状态展示。我们可以使用 ButtonStyle 和 MaterialStateProperty 来定义按钮样式、文本样式、颜色、字体、阴影等等。如果你需要在全局范围内应用某个样式,可以使用 Theme 来定义全局主题。

除了以上介绍的基本用法,ButtonStyle 还有一些高级用法,可以让我们更好地定制控件样式。下面我们将一一介绍。

5.Stateful Button

如果你需要自定义一些不同状态下的样式,可以使用 StatefulButton。StatefulButton 继承自 StatefulWidget,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。

举个例子,我们可以创建一个带有自定义选中状态的按钮:

  1. class MyStatefulButton extends StatefulWidget {
  2. const MyStatefulButton({Key? key}) : super(key: key);
  3. @override
  4. _MyStatefulButtonState createState() => _MyStatefulButtonState();
  5. }
  6. class _MyStatefulButtonState extends State<MyStatefulButton> {
  7. final ValueNotifier<bool> _selected = ValueNotifier(false);
  8. @override
  9. Widget build(BuildContext context) {
  10. return ValueListenableBuilder(
  11. valueListenable: _selected,
  12. builder: (BuildContext context, bool isSelected, Widget? child) {
  13. return TextButton(
  14. onPressed: () {
  15. setState(() {
  16. _selected.value = !_selected.value;
  17. });
  18. },
  19. style: ButtonStyle(
  20. backgroundColor: MaterialStateProperty.all(
  21. isSelected ? Colors.blue : Colors.grey,
  22. ),
  23. foregroundColor: MaterialStateProperty.all(Colors.white),
  24. textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
  25. ),
  26. child: Text('Button'),
  27. );
  28. },
  29. );
  30. }
  31. }

在上述代码中,我们定义了一个 MyStatefulButton,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。在 build 方法中,我们使用 ValueListenableBuilder 来监听选中状态的变化,并根据选中状态来更新按钮的样式。

6.Button Bar

如果你需要创建一个按钮组,可以使用 ButtonBar。ButtonBar 是一个将多个按钮组合在一起的控件,它支持垂直或水平排列按钮,并且可以根据需要自动对齐按钮。

举个例子,我们可以创建一个带有多个按钮的 ButtonBar:

  1. ButtonBar(
  2. alignment: MainAxisAlignment.center,
  3. children: [
  4. ElevatedButton(
  5. onPressed: () {},
  6. child: Text('Button 1'),
  7. ),
  8. ElevatedButton(
  9. onPressed: () {},
  10. child: Text('Button 2'),
  11. ),
  12. ElevatedButton(
  13. onPressed: () {},
  14. child: Text('Button 3'),
  15. ),
  16. ],
  17. )

在上述代码中,我们使用 ButtonBar 创建了一个带有三个 ElevatedButton 的按钮组。我们将 alignment 属性设置为 MainAxisAlignment.center,使按钮水平居中对齐。

自定义按钮形状

如果你需要创建一个自定义形状的按钮,可以使用 ShapeBorder。ShapeBorder 是一个抽象类,它定义了一个形状。我们可以继承 ShapeBorder 来创建自定义形状。

举个例子,我们可以创建一个圆形按钮:

  1. class CircleBorder extends ShapeBorder {
  2. const CircleBorder();
  3. @override
  4. EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
  5. @override
  6. Path
  7. getInnerPath(Rect rect, {TextDirection? textDirection}) {
  8. return getOuterPath(rect, textDirection: textDirection);
  9. }
  10. @override
  11. Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
  12. return Path()
  13. ..addOval(rect);
  14. }
  15. @override
  16. void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
  17. @override
  18. ShapeBorder scale(double t) {
  19. return CircleBorder();
  20. }
  21. }

在上述代码中,我们定义了一个 CircleBorder 类,它继承自 ShapeBorder。在 getOuterPath 方法中,我们使用 Path.addOval 方法创建了一个圆形的 Path。在 paint 方法中,我们什么都不做,因为我们只是想创建一个圆形形状的按钮。

接下来,我们可以使用 CircleBorder 创建一个圆形的按钮:

  1. ElevatedButton(
  2. onPressed: () {},
  3. child: Text('Button'),
  4. style: ButtonStyle(
  5. shape: MaterialStateProperty.all(CircleBorder()),
  6. ),
  7. )

在上述代码中,我们使用 CircleBorder 创建了一个圆形的按钮。我们将 shape 属性设置为 MaterialStateProperty.all(CircleBorder()),表示按钮的形状是一个 CircleBorder。

7.自定义按钮效果

如果你需要创建一个自定义效果的按钮,可以使用 InkResponse。InkResponse 是一个将水波纹效果添加到任何 Widget 的控件,它支持自定义水波纹颜色、形状等属性。

举个例子,我们可以创建一个带有自定义水波纹效果的按钮:

  1. InkResponse(
  2. onTap: () {},
  3. child: Container(
  4. padding: EdgeInsets.all(16),
  5. child: Text('Button'),
  6. decoration: BoxDecoration(
  7. color: Colors.grey,
  8. borderRadius: BorderRadius.circular(8),
  9. ),
  10. ),
  11. splashColor: Colors.red,
  12. highlightColor: Colors.yellow,
  13. borderRadius: BorderRadius.circular(8),
  14. )

在上述代码中,我们使用 InkResponse 创建了一个带有自定义水波纹效果的按钮。在 onTap 回调中,我们处理按钮的点击事件。我们将 child 属性设置为一个 Container,用来包含按钮的文本。我们将 decoration 属性设置为 BoxDecoration,用来定义按钮的背景颜色和圆角。我们将 splashColor 和 highlightColor 属性分别设置为 Colors.red 和 Colors.yellow,用来定义水波纹的颜色。最后,我们将 borderRadius 属性设置为 BorderRadius.circular(8),用来定义按钮的圆角半径。

总结

通过本文的介绍,我们学习了 ButtonStyle 的基本用法和高级用法,包括使用 MaterialStateProperty、StatefulButton、ButtonBar、自定义按钮形状和自定义按钮效果。通过这些技巧,我们可以更好地定制 Flutter 控件的样式,从而创建更好的用户体验。

写作不易,留个关注,收藏哦!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/302595
推荐阅读
相关标签
  

闽ICP备14008679号