继续创作,加速生长!这是我参加「日新方案 10 月更文挑战」的第 2 天,点击查看活动概况
0. 按钮一族现状
随着 Flutter 3.3
的发布,RaisedButton
组件从 Flutter
框架中移除,曾为界面开疆拓土的 按钮三兄弟
完全成为前史。
别的 MaterialButton
、RawMaterialButton
也将在未来方案被废弃,所以不建议大家再运用了:
现在,取而代之的是 TextButton
、ElevatedButton
、 OutlinedButton
三个按钮组件,本文将重点介绍这三者的运用办法。
别的,一些简单的按钮封装组件仍可运用:
CupertinoButton : iOS 风格按钮
CupertinoNavigationBarBackButton : iOS 导航栏回来按钮
BackButton : 回来按钮
IconButton : 图标按钮
CloseButton : 封闭按钮
FloatingActionButton : 起浮按钮
还有一些 多按钮
集成的组件,将在后续文章中具体介绍:
CupertinoSegmentedControl
CupertinoSlidingSegmentedControl
ButtonBar
DropdownButton
ToggleButtons
1. 三个按钮组件的默许体现
如下,是 ElevatedButton
的默许体现:有圆角和阴影,在点击时有水波纹。结构时有必要传入点击回调函数onPressed
和子组件 child
:
ElevatedButton(
onPressed: () {},
child: Text('ElevatedButton'),
),
如下,是 OutlinedButton
的默许体现:有圆角和外边线,内部无填充,在点击时有水波纹。结构时有必要传入点击回调函数onPressed
和子组件 child
:
OutlinedButton(
onPressed: () {},
child: Text('OutlinedButton'),
);
如下,是 TextButton
的默许体现:无边线,无填充,在点击时有水波纹。结构时有必要传入点击回调函数onPressed
和子组件 child
:
TextButton(
onPressed: () {},
child: Text('TextButton'),
);
2. 按钮款式的更改
假如稍微翻一下源码就能够看到,这三个按钮本质上是一样的,都是 ButtonStyleButton
的衍生类。只不过他们的默许款式 ButtonStyle
不同而已:
如下所示,在 ButtonStyleButton
类中队列两个笼统办法,需求子类去完成,回来默许按钮款式:
拿下面的 ElevatedButton
组件来说,它需求完成 defaultStyleOf
办法来回来默许主题。在未运用 Material3
时,经过 styleFrom
静态办法依据主题进行相关特点设置:比如各种颜色、阴影、文字款式、边距、形状等。
所以,需求修正按钮款式,只需供给 style
特点设置即可:该特点类型为 ButtonStyle
,三个按钮组件都供给了 styleFrom
静态办法创建 ButtonStyle
目标,运用如下:
ButtonStyle style = ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
foregroundColor: Colors.white,
elevation: 0,
padding: const EdgeInsets.symmetric(horizontal: 40),
shape: const StadiumBorder(),
side: const BorderSide(color: Colors.black,),
);
ElevatedButton(
onPressed: () {},
child: Text('Login'),
style: style
);
经过指定 shape
能够形状,如下所示,经过 CircleBorder
完成圆形组件:
ButtonStyle style = ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
elevation: 2,
shape: const CircleBorder(),
);
ElevatedButton(
onPressed: () {},
style: style,
child: const Icon(Icons.add)
);
TextButton
、ElevatedButton
、 OutlinedButton
这三个按钮,只是默许主题不同。假如供给相同的装备,OutlinedButton
因为能够完成下面的显现作用。
ButtonStyle style = OutlinedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
elevation: 0,
shape: const CircleBorder(),
side:BorderSide.none
);
OutlinedButton(
onPressed: () {},
style: style,
child: const Icon(Icons.add)
);
常见款式特点:
特点名 | 类型 | 用处 |
---|---|---|
foregroundColor | Color? | 前景色 |
backgroundColor | Color? | 背景色 |
disabledForegroundColor | Color? | 禁用时前景色 |
disabledBackgroundColor | Color? | 禁用时背景色 |
shadowColor | Color? | 阴影色 |
elevation | double? | 阴影深度 |
textStyle | TextStyle? | 文字款式 |
padding | EdgeInsetsGeometry? | 边距 |
side | BorderSide? | 边线 |
shape | OutlinedBorder? | 形状 |
别的,还有一些不常用的特点,了解一下即可:
特点名 | 类型 | 用处 |
---|---|---|
alignment | AlignmentGeometry? | 子组件区域中对齐办法 |
enableFeedback | bool? | 是否启用反应,如长按轰动 |
enabledMouseCursor | MouseCursor? | 桌面端鼠标款式 |
disabledMouseCursor | MouseCursor? | 禁用时桌面端鼠标款式 |
animationDuration | Duration? | 动画时长 |
minimumSize | Size? | 最小尺度 |
maximumSize | Size? | 最大尺度 |
fixedSize | Size? | 固定尺度 |
padding | EdgeInsetsGeometry? | 边距 |
3. 按钮的事情
这三个按钮在结构时都需求传入 onPressed
参数作为点击回调。别的,还有三个回调 onLongPress
用于监听长按事情;onHover
用于监听鼠标悬浮事情;onFocusChange
用于监听焦点改变的事情。
ElevatedButton(
onPressed: () {
print('========Login==========');
},
onHover: (bool value) {
print('=====onHover===$value==========');
},
onLongPress: () {
print('========onLongPress==========');
},
onFocusChange: (bool focus) {
print('=====onFocusChange===$focus==========');
},
child: const Text('Login'),
);
当按钮的 onPressed
和 onLongPress
都为 null
时,按钮会处于 禁用状况
。此刻按钮不会呼应点击,也没有水波纹作用;别的,按钮的背景色,前景色分别取用 disabledBackgroundColor
和 disabledForegroundColor
特点:
ElevatedButton(
onPressed: null,
style: style,
child: const Text('Login'),
);
4. 按钮的尺度
在按钮默许款式中,规则了最小尺度是 Size(64, 36)
, 最大尺度无限。
也便是说,在父级区域束缚的允许规模,按钮的尺度由 子组件
和 边距
确定的。如下所示,子组件中文字非常大,按钮尺度会适用文字的大小。
ButtonStyle style = ElevatedButton.styleFrom(
// 略...
padding: const EdgeInsets.symmetric(horizontal: 40,vertical: 10),
);
ElevatedButton(
onPressed: null,
style: style,
child: const Text('Login',style: TextStyle(fontSize: 50),),
);
父级束缚
是绝对不能违逆的,在紧束缚下,按钮的尺度会被锁死。如下,经过 SizedBox
为按钮施加一个 200*40
的紧束缚:
SizedBox(
width: 200,
height: 40,
child: ElevatedButton(
onPressed: (){},
style: style,
child: const Text('Login'),
),
);
如下,将紧束缚宽度设为 10
,能够看出按钮也只能遵循。即使它本身最小尺度是 Size(64, 36)
,也不能违背父级的束缚:
所以,想要修正按钮的尺度,有两种办法:
-
- 从
子组件尺度 边距
下手,调整按钮尺度。
- 从
-
- 为按钮施加
紧束缚
,锁死按钮尺度。
- 为按钮施加
5. 简看 ButtonStyleButton 组件的源码完成
首先,ButtonStyleButton
是一个笼统类,其继承自 StatefulWidget
, 阐明其需求依赖状况类完成内部的改变。
在 createState
办法中回来 _ButtonStyleState
状况目标,阐明按钮构建的逻辑在该状况类中:
@override
State<ButtonStyleButton> createState() => _ButtonStyleState();
直接来看 _ButtonStyleState
中的结构办法,一开始会触发组件的 themeStyleOf
和 defaultStyleOf
笼统办法获取 ButtonStyle
目标。这也便是TextButton
、ElevatedButton
、 OutlinedButton
三者作为完成类需求完成的逻辑。
构建的组件也便是按钮的终究体现,其间运用了 ConstrainedBox
组件处理束缚;Material
组件处理根本体现内容;InkWell
处理水波纹和相关事情;Padding
用于处理内边距;Align
处理对齐办法。
运用,总的来看:ButtonStyleButton
组件便是一些常用组件的组合体而已,经过 ButtonStyle
类进行款式装备,来简化构建逻辑。经过封装,简化运用。别的,我们能够经过主题来统一款式,无需一个个进行装备,这个在后面进行介绍。那本文就到这里,谢谢观看 ~