继续创作,加速生长!这是我参加「日新方案 10 月更文挑战」的第 2 天,点击查看活动概况


0. 按钮一族现状

随着 Flutter 3.3 的发布,RaisedButton 组件从 Flutter 框架中移除,曾为界面开疆拓土的 按钮三兄弟 完全成为前史。

Flutter 组件集录 | 新一代 Button 按钮参上

别的 MaterialButtonRawMaterialButton 也将在未来方案被废弃,所以不建议大家再运用了:

Flutter 组件集录 | 新一代 Button 按钮参上


现在,取而代之的是 TextButtonElevatedButtonOutlinedButton 三个按钮组件,本文将重点介绍这三者的运用办法。

Flutter 组件集录 | 新一代 Button 按钮参上

别的,一些简单的按钮封装组件仍可运用:

CupertinoButton : iOS 风格按钮
CupertinoNavigationBarBackButton : iOS 导航栏回来按钮
BackButton : 回来按钮
IconButton : 图标按钮
CloseButton : 封闭按钮
FloatingActionButton : 起浮按钮

还有一些 多按钮 集成的组件,将在后续文章中具体介绍:

CupertinoSegmentedControl
CupertinoSlidingSegmentedControl
ButtonBar
DropdownButton
ToggleButtons

1. 三个按钮组件的默许体现

如下,是 ElevatedButton 的默许体现:有圆角和阴影,在点击时有水波纹。结构时有必要传入点击回调函数onPressed 和子组件 child :

Flutter 组件集录 | 新一代 Button 按钮参上

ElevatedButton(
  onPressed: () {},
  child: Text('ElevatedButton'),
),

如下,是 OutlinedButton 的默许体现:有圆角和外边线,内部无填充,在点击时有水波纹。结构时有必要传入点击回调函数onPressed 和子组件 child :

Flutter 组件集录 | 新一代 Button 按钮参上

OutlinedButton(
  onPressed: () {},
  child: Text('OutlinedButton'),
);

如下,是 TextButton 的默许体现:无边线,无填充,在点击时有水波纹。结构时有必要传入点击回调函数onPressed 和子组件 child :

Flutter 组件集录 | 新一代 Button 按钮参上

TextButton(
  onPressed: () {},
  child: Text('TextButton'),
);

2. 按钮款式的更改

假如稍微翻一下源码就能够看到,这三个按钮本质上是一样的,都是 ButtonStyleButton 的衍生类。只不过他们的默许款式 ButtonStyle 不同而已:

Flutter 组件集录 | 新一代 Button 按钮参上

如下所示,在 ButtonStyleButton 类中队列两个笼统办法,需求子类去完成,回来默许按钮款式:

Flutter 组件集录 | 新一代 Button 按钮参上


拿下面的 ElevatedButton 组件来说,它需求完成 defaultStyleOf 办法来回来默许主题。在未运用 Material3 时,经过 styleFrom 静态办法依据主题进行相关特点设置:比如各种颜色、阴影、文字款式、边距、形状等。

Flutter 组件集录 | 新一代 Button 按钮参上


所以,需求修正按钮款式,只需供给 style 特点设置即可:该特点类型为 ButtonStyle,三个按钮组件都供给了 styleFrom 静态办法创建 ButtonStyle 目标,运用如下:

Flutter 组件集录 | 新一代 Button 按钮参上

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 完成圆形组件:

Flutter 组件集录 | 新一代 Button 按钮参上

ButtonStyle style = ElevatedButton.styleFrom(
  backgroundColor: Colors.blue,
  foregroundColor: Colors.white,
  elevation: 2,
  shape: const CircleBorder(),
);
ElevatedButton(
    onPressed: () {},
    style: style,
    child: const Icon(Icons.add)
);

TextButtonElevatedButtonOutlinedButton 这三个按钮,只是默许主题不同。假如供给相同的装备,OutlinedButton 因为能够完成下面的显现作用。

Flutter 组件集录 | 新一代 Button 按钮参上

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 用于监听焦点改变的事情。

Flutter 组件集录 | 新一代 Button 按钮参上

ElevatedButton(
  onPressed: () {
    print('========Login==========');
  },
  onHover: (bool value) {
    print('=====onHover===$value==========');
  },
  onLongPress: () {
    print('========onLongPress==========');
  },
  onFocusChange: (bool focus) {
    print('=====onFocusChange===$focus==========');
  },
  child: const Text('Login'),
);

当按钮的 onPressedonLongPress 都为 null 时,按钮会处于 禁用状况 。此刻按钮不会呼应点击,也没有水波纹作用;别的,按钮的背景色,前景色分别取用 disabledBackgroundColordisabledForegroundColor 特点:

Flutter 组件集录 | 新一代 Button 按钮参上

Flutter 组件集录 | 新一代 Button 按钮参上

ElevatedButton(
  onPressed: null,
  style: style,
  child: const Text('Login'),
);

4. 按钮的尺度

在按钮默许款式中,规则了最小尺度是 Size(64, 36) , 最大尺度无限。

Flutter 组件集录 | 新一代 Button 按钮参上

也便是说,在父级区域束缚的允许规模,按钮的尺度由 子组件边距 确定的。如下所示,子组件中文字非常大,按钮尺度会适用文字的大小。

Flutter 组件集录 | 新一代 Button 按钮参上

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 的紧束缚:

Flutter 组件集录 | 新一代 Button 按钮参上

SizedBox(
  width: 200,
  height: 40,
  child: ElevatedButton(
    onPressed: (){},
    style: style,
    child: const Text('Login'),
  ),
);

如下,将紧束缚宽度设为 10 ,能够看出按钮也只能遵循。即使它本身最小尺度是 Size(64, 36),也不能违背父级的束缚:

Flutter 组件集录 | 新一代 Button 按钮参上

所以,想要修正按钮的尺度,有两种办法:

    1. 子组件尺度 边距 下手,调整按钮尺度。
    1. 为按钮施加 紧束缚 ,锁死按钮尺度。

5. 简看 ButtonStyleButton 组件的源码完成

首先,ButtonStyleButton 是一个笼统类,其继承自 StatefulWidget, 阐明其需求依赖状况类完成内部的改变。

Flutter 组件集录 | 新一代 Button 按钮参上

createState 办法中回来 _ButtonStyleState 状况目标,阐明按钮构建的逻辑在该状况类中:

@override
State<ButtonStyleButton> createState() => _ButtonStyleState();

直接来看 _ButtonStyleState 中的结构办法,一开始会触发组件的 themeStyleOfdefaultStyleOf 笼统办法获取 ButtonStyle 目标。这也便是TextButtonElevatedButtonOutlinedButton 三者作为完成类需求完成的逻辑。

Flutter 组件集录 | 新一代 Button 按钮参上


构建的组件也便是按钮的终究体现,其间运用了 ConstrainedBox 组件处理束缚;Material 组件处理根本体现内容;InkWell 处理水波纹和相关事情;Padding 用于处理内边距;Align 处理对齐办法。

Flutter 组件集录 | 新一代 Button 按钮参上

运用,总的来看:ButtonStyleButton 组件便是一些常用组件的组合体而已,经过 ButtonStyle 类进行款式装备,来简化构建逻辑。经过封装,简化运用。别的,我们能够经过主题来统一款式,无需一个个进行装备,这个在后面进行介绍。那本文就到这里,谢谢观看 ~