Flutter基建 - 按钮全解析

本篇基于Flutter 3.13.9,Dart 3.1.5版本

Flutter 3.13.9 • channel stable • github.com/flutter/flu...

Framework • revision d211f42860 (2 weeks ago) • 2023-10-25 13:42:25 -0700

Engine • revision 0545f8705d

Tools • Dart 3.1.5 • DevTools 2.25.0

本篇为Flutter基建的第四篇文章,主要介绍Flutter中按钮相关组件,在按钮组件这方面,Flutter为开发者提供了非常全面的样式,总结下来可以分为普通按钮、图标按钮、动作按钮和开关按钮,在日常使用Flutter开发过程中,很多的样式都无需自己在封装一套,可以使用原生提供的这些样式拿来即用,下面我们逐一学习下这样按钮的使用。

Flutter基建 - Dart基础类型

Flutter基建 - Dart方法和类

Flutter基建 - 文本组件

Flutter基建 - 按钮全解析

普通样式按钮ButtonStyleButton

此系列的按钮是我们日常开发中接触最多的一种样式了,它实现的效果就如它名称一样,一种按钮样式的按钮(哈哈🤣),此样式按钮一共有四种子类,分别为TextButton、ElevatedButton、FilledButton和OutlinedButton,那么我们就进入实战环节看看这些按钮实现的具体效果吧。

TextButton

TextButton是一种文本按钮,用于显示单纯文本并且不加任何边框和阴影修饰的一种按钮,使用起来也是极为简单

less 复制代码
TextButton(
  onPressed: () {},
  child: const Text("Text Button"),
),

正常状态下样式:

手指按下时样式:

可以看到TextButton在正常状态下看上去就是一个文本组件,没有其它任何修饰,只是在手指按下去之后会有个圆润的背景阴影。

TextButton有一个必传参数就是onPressed,用于检测点击事件,可以在此事件回调中处理点击事件的具体逻辑;onLongPressed则是用于检测长按事件。

ElevatedButton

ElevatedButton可以理解为TextButton的提升版,加上了背景颜色和带弧度的边框,并且在手指按下去之后,它的背景色会加深,有个明显的区别。

less 复制代码
ElevatedButton(
  onPressed: () {},
  child: const Text('ElevatedButton'),
),

正常状态下样式:

手指按下时样式:

FilledButton

FilledButton为填充样式的按钮,说白了就是给背景上个色,这种样式在手指点击时给人的观感不是很强烈,只有微弱的颜色变化,大家可以自己感受一下。

less 复制代码
FilledButton(
  onPressed: () {},
  child: const Text('FilledButton'),
),

正常状态下样式:

手指按下时样式:

OutlinedButton

OutlinedButton区别则是在于边框,它的背景色默认为白色,给边框添加了主题色。

less 复制代码
OutlinedButton(
  onPressed: () {},
  child: const Text('OutlinedBut
),

正常状态下样式:

手指按下时样式:

上面就是ButtonStyleButton四种样式的按钮,每一种都有自己的特色,小伙伴们可以按需选择,如果都不满足自己的需要也可以使用ButtonStyleButton自定义自己的按钮样式,下面我们以这种形式自己定义一套目标的样式。

less 复制代码
TextButton(
  onPressed: () {},
  style: const ButtonStyle(
    backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
    elevation: MaterialStatePropertyAll(10.0),
    shape: MaterialStatePropertyAll(
      RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(15)),
        side: BorderSide(color: Colors.black, width: 0.5),
      ),
    ),
  ),
  child: const Text(
    'CustomButton',
    style: TextStyle(color: Colors.white),
  ),
),

这里我们使用TextButton方法中style参数自定义了一套按钮的样式,style参数为ButtonStyle类型,ButtonStyle类中可以使用backgroundColor自定义背景颜色,这里需要注意的是传入的为MaterialStatePropertyAll类型;elevation用于定义阴影;shape用于定义按钮的边框,这里使用的是RoundedRectangleBorder,在内部定义了15的圆弧角度和边框宽度为0.5颜色为黑色样式,实现的效果如上图所示。

上面这样实现方式有可能会觉得复杂,也可以在child的文本组件中定义想要的样式,这里就不过多介绍了~

IconButton

图标按钮

IconButton是专门为图标按钮设计的,它的样式仅显示一个Icon,有点类似单纯的Icon组件,不过它增加了许多额外的属性,下面我们来看看IconButton具体的实现。

ini 复制代码
var iconButtonIsSelected = false;

IconButton(
  onPressed: () {
    setState(() {
      iconButtonIsSelected = !iconButtonIsSelected;
    });
  },
  selectedIcon: const Icon(Icons.person_outline),
  isSelected: iconButtonIsSelected,
  color: Colors.green,
  icon: const Icon(Icons.person),
),

正常状态下样式:

selected状态下样式:

IconButton提供了正常状态和selected状态下不同的样式,我们可以分别给这两种状态设置不一样的Icon图标,并且还可以通过color参数给Icon设置自定义的颜色值。

如果需要使用单独的Icon按钮,可以采用IconButton来实现。其实除了IconButton以外,Flutter还提供了图标+文本样式的按钮,相对于IconButton样式图标+文本样式的按钮在日常开发中使用的过多一点,接下来我们看看这种样式是如何实现的。

图标+文本按钮

less 复制代码
TextButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.add),
  label: const Text('add'),
),
ElevatedButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.add),
  label: const Text('add'),
),
FilledButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.add),
  label: const Text('add'),
),
OutlinedButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.add),
  label: const Text('add'),
),

普通按钮样式的TextButton、ElevatedButton、FilledButton和OutlinedButton都提供了icon()的扩展方法,用于实现按钮文字前面加图标的功能,在用法上面只是多了Widget icon和Widget label两个参数,分别用于显示图标和提示文本的效果。

ActionButton

ActionButton

ActionButton其实就是Flutter给我们额外封装了一层的IconButton,它内部还是采用的IconButton来实现,可以先看一下它的构造方法:

kotlin 复制代码
const _ActionButton({
  super.key,
  this.color,
  required this.icon,
  required this.onPressed,
  this.style,
});

构造方法还是比较简单的,定义了color颜色值、icon图标、onPressed点击事件和style按钮样式,然后在其内部的build(context)方法中直接调用了IconButton🤣,这里注意一点就是点击事件,如果我们传入了onPressed参数,那么就会采用我们传入的回调,否则就会直接调用_onPressedCallback(context)方法,此方法下面会介绍。

scss 复制代码
@override
Widget build(BuildContext context) {
  assert(debugCheckHasMaterialLocalizations(context));
  return IconButton(
    icon: icon,
    style: style,
    color: color,
    tooltip: _getTooltip(context),
    onPressed: () {
      if (onPressed != null) {
        onPressed!();
      } else {
        _onPressedCallback(context);
      }
    },
  );
}

它是一个抽象类,我们不可以直接拿来使用,Flutter帮我们封装了几种特定的ActionButton,分别为:BackButton、CloseButton、DrawerButton和EndDrawerButton。

具体样式

scss 复制代码
BackButton(),
CloseButton(),
DrawerButton(),
EndDrawerButton()

这四种样式的ActionButton使用起来应该是最为简单的了,可以不传入任何参数,直接引入即可,这里我们挑BackButton看看内部的实现是如何。

scala 复制代码
class BackButton extends _ActionButton {
  const BackButton({
    super.key,
    super.color,
    super.style,
    super.onPressed,
  }) : super(icon: const BackButtonIcon());

  @override
  void _onPressedCallback(BuildContext context) => Navigator.maybePop(context);

  @override
  String _getTooltip(BuildContext context) {
    return MaterialLocalizations.of(context).backButtonTooltip;
  }
}

BackButton内部实现也是极为简单的,构造方法中实现了父类的icon参数,传入了BackButtonIcon(),这个返回Icon组件,然后复写了_onPressedCallback方法,调用的是Navigator.maybePop(),此方法意思就是将当前页面退出页面堆栈,通俗来说就是退出当前页面,Navigator知识后续文章会详细介绍。

看到这大致就明白了BackButton的具体实现了,如果我们需要一个点击退出界面的按钮,可以考虑使用BackButton组件,毕竟Flutter已经为我们实现好了逻辑。

其余三个ActionButton就不再一一介绍了,小伙伴可以自行阅读源码哈~

ToggleButtons

ToggleButtons是一个特殊的按钮,说它是按钮其实有点勉强,它其实是一组可以开关的按钮,根据当前开关的状态有不一样的表现,子组件为List,并且子组件中每一个都可以相应onPressed点击事件。

ini 复制代码
var isSelected = [false, false, false];

ToggleButtons(
  isSelected: isSelected,
  onPressed: (int index) {
    setState(() {
      isSelected[index] = !isSelected[index];
    });
  },
  children: const <Widget>[
    Icon(Icons.person),
    Icon(Icons.email),
    Icon(Icons.home),
  ],
),

这里我们分别介绍下三个重要的参数:

  • isSelected参数为List类型,根据子组件的数量,需要传入对应大小的bool列表,这里默认开关都是关闭状态;
  • onPressed参数为Function(int index)类型,index就是点击的子组件对应的下标,这里就是将对应下标的状态置为相反值;
  • children参数为List类型,需要传入和isSelected大小一致的组件数量。

最后来看看具体效果:

写在最后

本篇文章全面的介绍了Flutter中按钮的相关知识,希望可以帮助大家了进一步了解和熟悉按钮的相关知识,后续会循序渐进逐步接触Flutter更多的知识。

我是Taonce,如果觉得本文对你有所帮助,帮忙关注、赞或者收藏三连一下,谢谢😆😆~

相关推荐
weixin_4493108429 分钟前
高效集成:聚水潭采购数据同步到MySQL
android·数据库·mysql
Zender Han44 分钟前
Flutter自定义矩形进度条实现详解
android·flutter·ios
hello world smile44 分钟前
关于Flutter空安全升级方案整理
flutter·移动端
白乐天_n3 小时前
adb:Android调试桥
android·adb
姑苏风7 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
数据猎手小k10 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
你的小1011 小时前
JavaWeb项目-----博客系统
android
风和先行11 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.12 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰13 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder