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 中,我们可以这样写:
FlatButton(
onPressed: () {},
color: Colors.blue,
hoverColor: Colors.green,
child: Text('Button'),
)
但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:
TextButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.hovered)) {
return Colors.green;
}
return Colors.blue;
}),
),
child: Text('Button'),
)
在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的背景颜色,这样就可以轻松地实现不同状态下的样式切换。在这个例子中,我们使用 MaterialState.hovered 来处理按钮悬停时的样式。
需要注意的是,MaterialStateProperty 不仅适用于按钮,还适用于其他控件,例如 Checkbox、Radio、Slider 等。
2.ButtonStyle
ButtonStyle 是 Flutter 中一种全新的样式定义方式,它用于定义控件的样式。ButtonStyle 的设计目的是为了在不同平台下提供一致的外观和行为。例如,当用户在不同的操作系统上运行应用程序时,ButtonStyle 可以确保按钮的样式和行为都是一致的。
ButtonStyle 由多个 MaterialStateProperty 组成,每个 MaterialStateProperty 对应一个控件状态。我们可以使用 MaterialStateProperty 来定义控件不同状态下的样式。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在不同状态下的背景颜色、前景色、字体大小等。
举个例子,假设我们需要创建一个带有自定义样式的按钮。在Flutter 1 中,我们可以这样写:
FlatButton(
onPressed: () {},
color: Colors.blue,
textColor: Colors.white,
child: Text('Button'),
)
但是在Flutter 2 中,我们需要使用 ButtonStyle 和 MaterialStateProperty 来实现相同的效果。代码如下:
TextButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
),
child: Text('Button'),
)
在上述代码中,我们使用MaterialStateProperty.all 方法来设置按钮的背景颜色、前景色和字体大小。MaterialStateProperty.all 方法可以将一个值应用到所有的状态中。
需要注意的是,ButtonStyle 的属性有很多,例如 elevation、padding、shape 等等。我们可以使用 MaterialStateProperty 来设置每个属性在不同状态下的值。例如,我们可以通过定义 MaterialStateProperty 来修改按钮在悬停状态下的阴影。
TextButton(
onPressed: () {},
style: ButtonStyle(
elevation: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.hovered)) {
return 10.0;
}
return 5.0;
}),
),
child: Text('Button'),
)
在上述代码中,我们使用MaterialStateProperty.resolveWith 方法来处理按钮的阴影。当按钮处于悬停状态时,我们将阴影的值设置为 10.0,否则设置为 5.0。
3.Theme
如果你希望在全局范围内应用某个样式,可以使用Flutter 中的 Theme。Theme 可以用来定义全局主题,包括文本样式、颜色、字体、按钮样式等等。在 ButtonStyle 中,我们也可以使用 Theme 来定义全局按钮样式。
举个例子,假设我们需要在全局范围内应用自定义按钮样式。我们可以这样写:
Theme(
data: ThemeData(
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor: MaterialStateProperty.all(Colors.white),
textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
),
),
),
child: TextButton(
onPressed: () {},
child: Text('Button'),
),
)
在上述代码中,我们使用Theme 来定义全局的按钮样式。我们将 ButtonStyle 定义在 textButtonTheme 中,并将其应用到 TextButton 中。
4.在Flutter 中,ButtonStyle 和 MaterialStateProperty 为我们提供了一种更加灵活、可定制的方式来定义控件样式。ButtonStyle 和 MaterialStateProperty 可以帮助我们实现不同状态下的样式切换,并支持不同平台下的交互状态展示。我们可以使用 ButtonStyle 和 MaterialStateProperty 来定义按钮样式、文本样式、颜色、字体、阴影等等。如果你需要在全局范围内应用某个样式,可以使用 Theme 来定义全局主题。
除了以上介绍的基本用法,ButtonStyle 还有一些高级用法,可以让我们更好地定制控件样式。下面我们将一一介绍。
5.Stateful Button
如果你需要自定义一些不同状态下的样式,可以使用 StatefulButton。StatefulButton 继承自 StatefulWidget,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。
举个例子,我们可以创建一个带有自定义选中状态的按钮:
class MyStatefulButton extends StatefulWidget {
const MyStatefulButton({Key? key}) : super(key: key);
@override
_MyStatefulButtonState createState() => _MyStatefulButtonState();
}
class _MyStatefulButtonState extends State<MyStatefulButton> {
final ValueNotifier<bool> _selected = ValueNotifier(false);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: _selected,
builder: (BuildContext context, bool isSelected, Widget? child) {
return TextButton(
onPressed: () {
setState(() {
_selected.value = !_selected.value;
});
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
isSelected ? Colors.blue : Colors.grey,
),
foregroundColor: MaterialStateProperty.all(Colors.white),
textStyle: MaterialStateProperty.all(TextStyle(fontSize: 20)),
),
child: Text('Button'),
);
},
);
}
}
在上述代码中,我们定义了一个 MyStatefulButton,它包含了一个 ValueNotifier<bool>,用来表示按钮的选中状态。在按钮选中时,我们可以自定义按钮的样式。在 build 方法中,我们使用 ValueListenableBuilder 来监听选中状态的变化,并根据选中状态来更新按钮的样式。
6.Button Bar
如果你需要创建一个按钮组,可以使用 ButtonBar。ButtonBar 是一个将多个按钮组合在一起的控件,它支持垂直或水平排列按钮,并且可以根据需要自动对齐按钮。
举个例子,我们可以创建一个带有多个按钮的 ButtonBar:
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {},
child: Text('Button 1'),
),
ElevatedButton(
onPressed: () {},
child: Text('Button 2'),
),
ElevatedButton(
onPressed: () {},
child: Text('Button 3'),
),
],
)
在上述代码中,我们使用 ButtonBar 创建了一个带有三个 ElevatedButton 的按钮组。我们将 alignment 属性设置为 MainAxisAlignment.center,使按钮水平居中对齐。
自定义按钮形状
如果你需要创建一个自定义形状的按钮,可以使用 ShapeBorder。ShapeBorder 是一个抽象类,它定义了一个形状。我们可以继承 ShapeBorder 来创建自定义形状。
举个例子,我们可以创建一个圆形按钮:
class CircleBorder extends ShapeBorder {
const CircleBorder();
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override
Path
getInnerPath(Rect rect, {TextDirection? textDirection}) {
return getOuterPath(rect, textDirection: textDirection);
}
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
return Path()
..addOval(rect);
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}
@override
ShapeBorder scale(double t) {
return CircleBorder();
}
}
在上述代码中,我们定义了一个 CircleBorder 类,它继承自 ShapeBorder。在 getOuterPath 方法中,我们使用 Path.addOval 方法创建了一个圆形的 Path。在 paint 方法中,我们什么都不做,因为我们只是想创建一个圆形形状的按钮。
接下来,我们可以使用 CircleBorder 创建一个圆形的按钮:
ElevatedButton(
onPressed: () {},
child: Text('Button'),
style: ButtonStyle(
shape: MaterialStateProperty.all(CircleBorder()),
),
)
在上述代码中,我们使用 CircleBorder 创建了一个圆形的按钮。我们将 shape 属性设置为 MaterialStateProperty.all(CircleBorder()),表示按钮的形状是一个 CircleBorder。
7.自定义按钮效果
如果你需要创建一个自定义效果的按钮,可以使用 InkResponse。InkResponse 是一个将水波纹效果添加到任何 Widget 的控件,它支持自定义水波纹颜色、形状等属性。
举个例子,我们可以创建一个带有自定义水波纹效果的按钮:
InkResponse(
onTap: () {},
child: Container(
padding: EdgeInsets.all(16),
child: Text('Button'),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(8),
),
),
splashColor: Colors.red,
highlightColor: Colors.yellow,
borderRadius: BorderRadius.circular(8),
)
在上述代码中,我们使用 InkResponse 创建了一个带有自定义水波纹效果的按钮。在 onTap 回调中,我们处理按钮的点击事件。我们将 child 属性设置为一个 Container,用来包含按钮的文本。我们将 decoration 属性设置为 BoxDecoration,用来定义按钮的背景颜色和圆角。我们将 splashColor 和 highlightColor 属性分别设置为 Colors.red 和 Colors.yellow,用来定义水波纹的颜色。最后,我们将 borderRadius 属性设置为 BorderRadius.circular(8),用来定义按钮的圆角半径。
总结
通过本文的介绍,我们学习了 ButtonStyle 的基本用法和高级用法,包括使用 MaterialStateProperty、StatefulButton、ButtonBar、自定义按钮形状和自定义按钮效果。通过这些技巧,我们可以更好地定制 Flutter 控件的样式,从而创建更好的用户体验。文章来源:https://www.toymoban.com/news/detail-786349.html
写作不易,留个关注,收藏哦!!文章来源地址https://www.toymoban.com/news/detail-786349.html
到了这里,关于Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!