文本按钮(TextButton)

按钮是 Flutter 中最常见的组件之一。其中的种类也很多:

  • ButtonStyleButton
    • 文本按钮(TextButton
    • ElevatedButton
    • OutlinedButton
  • DropdownButton
  • IconButton
  • FloatingActionButton
  • PopupMenuButton

今天我们主要来研究下文本按钮。文本按钮是一种使用文字(Text)和图标(Icon)作为内容的按钮。

构建方法

const TextButton({
    Key? key,
    // 文本按钮的内容,一般为文字(`Text`)或图标(`Icon`)
    required Widget child,
    // 点击回调函数
    required VoidCallback? onPressed,
    // 长按回调函数
    VoidCallback? onLongPress,
    // 文本按钮的样式
    ButtonStyle? style,
    ValueChanged<bool>? onHover,
    ValueChanged<bool>? onFocusChange,
    FocusNode? focusNode,
    bool autofocus = false,
    Clip clipBehavior = Clip.none,
  })
// 快捷的构建方法
// 创建一个左边是图标,右边是文字的文本按钮
factory TextButton.icon({
    Key? key,
    required VoidCallback? onPressed,
    VoidCallback? onLongPress,
    ValueChanged<bool>? onHover,
    ValueChanged<bool>? onFocusChange,
    ButtonStyle? style,
    FocusNode? focusNode,
    bool? autofocus,
    Clip? clipBehavior,
    required Widget icon,
    required Widget label,
  })

我们平时主要会用到以下几个属性:

  • required Widget child
  • required VoidCallback? onPressed
  • VoidCallback? onLongPress
  • ButtonStyle? style

怎么使用?

// 一个可以点击的文本按钮
TextButton(
  onPressed: () => print('onPressed'),
  onLongPress: () => print('onLongPress'),
  child: const Text('Enabled'),
  style: TextButton.styleFrom(primary: Colors.red),
)

// 一个不可以点击的文本按钮
const TextButton(
  onPressed: null,
  child: Text('Disabled'),
)

// 一个由图标和文字组成的文本按钮
TextButton.icon(
  onPressed: () {},
  icon: const Icon(Icons.email),
  label: const Text('Send Email'),
)

使用起来很直观明了,这里面主要复杂的就是按钮的样式 style。我们接下来就来详细了解下按钮的样式构成。

ButtonStyle? style

const ButtonStyle({
    this.textStyle,
    this.backgroundColor,
    this.foregroundColor,
    this.overlayColor,
    this.shadowColor,
    this.elevation,
    this.padding,
    this.minimumSize,
    this.fixedSize,
    this.maximumSize,
    this.side,
    this.shape,
    this.mouseCursor,
    this.visualDensity,
    this.tapTargetSize,
    this.animationDuration,
    this.enableFeedback,
    this.alignment,
    this.splashFactory,
  });
  • textStyle
    • final MaterialStateProperty<TextStyle?>? textStyle;
    • 按钮内容中的 Text 的样式。
    • 但是对于 Text 的颜色,我们一般使用 foregroundColor 来设置。
  • backgroundColor
    • final MaterialStateProperty<Color?>? backgroundColor;
    • 按钮的背景填充颜色
  • foregroundColor
    • final MaterialStateProperty<Color?>? foregroundColor;
    • 按钮内容的颜色,按钮内容一般为文本(Text)或图标(Icon)。
  • overlayColor
    • final MaterialStateProperty<Color?>? overlayColor;
    • 按钮高亮的颜色,当按钮的状态为按下(pressed)、focusedhovered 时显示
  • shadowColor
    • final MaterialStateProperty<Color?>? shadowColor;
    • 按钮的阴影颜色
  • elevation
    • final MaterialStateProperty<double?>? elevation;
    • 按钮的 elevation
  • padding
    • final MaterialStateProperty<EdgeInsetsGeometry?>? padding;
    • 按钮的边框和内容之间的间距
  • minimumSize
    • final MaterialStateProperty<Size?>? minimumSize;
    • 按钮的最小尺寸
    • 该值必须小于等于 maximumSize
  • fixedSize
    • final MaterialStateProperty<Size?>? fixedSize;
    • 按钮的尺寸
    • 设置了这个尺寸,仍然会收 minimumSizemaximumSize 的制约
    • 如果等于 double.infinity,就会被忽略
    • 如果想要固定宽度和默认高度的设置使用:Size.fromWidth(320)
    • 如果想要固定高度和默认宽度的设置使用:Size.fromHeight(100)
  • maximumSize
    • final MaterialStateProperty<Size?>? maximumSize;
    • 按钮的最大尺寸
    • Size.infinitenull 表示按钮的最大尺寸不受限制
    • 该值必须大于等于 minimumSize
  • side
    • final MaterialStateProperty<BorderSide?>? side;
    • 按钮轮廓的颜色和宽度
    • 该值和 shape 属性一起来创建和装饰按钮轮廓
  • shape
    • final MaterialStateProperty<OutlinedBorder?>? shape;
    • 按钮的形状
    • 该值和 side 属性一起来创建和装饰按钮轮廓
  • mouseCursor
    • MaterialStateProperty<MouseCursor?>? mouseCursor;
  • visualDensity
    • final VisualDensity? visualDensity;
  • tapTargetSize
    • final MaterialTapTargetSize? tapTargetSize;
    • 配置可按下按钮的区域的最小尺寸。
    • 总是默认为 ThemeData.materialTapTargetSize
  • animationDuration
    • final Duration? animationDuration;
    • 定义 shapeelevation 的动画变化的持续时间。
    • 通常,组件的默认值是 kThemeChangeDuration
  • enableFeedback
    • final bool? enableFeedback;
    • 检测到的手势是否应该提供声音和触觉反馈。
    • 通常,组件的默认值是 true
  • alignment
    • final AlignmentGeometry? alignment;
    • 按钮内容的对齐方式
    • 通常情况下,按钮的大小会调整为容纳它的内容和它的 padding。如果按钮的大小被限制在一个固定的尺寸内,例如用一个 SizedBox 来包围它,这个属性就定义了它的内容在可用空间内的对齐方式。
    • 总是默认为 Alignment.center
  • splashFactory
    • final InteractiveInkFeatureFactory? splashFactory;
    • 创建 InkWell splash factory,它定义了响应轻击而发生的 "墨水 "飞溅的外观效果。
    • splashFactory: NoSplash.splashFactory 会去除"墨水 "飞溅的效果。

TextButton.styleFrom

一般我们修改文本按钮的样式时不会直接创建一个 ButtonStyle,而是使用 TextButton.styleFrom 方法。这么做的好处是我们直接在原有的样式基础上修改,只需要修改你想要改动的部分,会简单很多。

  static ButtonStyle styleFrom({
    // 指定可点击状态下的文本按钮内容的颜色
    Color? primary,
    // 指定不可点击状态下的文本按钮的颜色
    Color? onSurface,
    // 指定文本按钮的背景颜色
    Color? backgroundColor,
    // 指定文本按钮的阴影颜色
    Color? shadowColor,
    // 指定文本按钮阴影的高度
    double? elevation,
    // 指定文本按钮内容文字样式
    TextStyle? textStyle,
    // 指定文本按钮内容与边框之间的 padding
    EdgeInsetsGeometry? padding,
    // 指定文本按钮最小的尺寸
    Size? minimumSize,
    // 指定文本按钮的固定尺寸
    Size? fixedSize,
    // 指定文本按钮的最大尺寸
    Size? maximumSize,
    // 指定文本按钮轮廓的颜色和宽度
    BorderSide? side,
    // 指定文本按钮的形状
    OutlinedBorder? shape,
    MouseCursor? enabledMouseCursor,
    MouseCursor? disabledMouseCursor,
    VisualDensity? visualDensity,
    // 指定配置可按下按钮的区域的最小尺寸。
    MaterialTapTargetSize? tapTargetSize,
    // 指定 `shape` 和 `elevation` 的动画变化的持续时间。
    Duration? animationDuration,
    // 指定是否应该提供声音和触觉反馈。
    bool? enableFeedback,
    // 指定按钮内容的对齐方式
    AlignmentGeometry? alignment,
    InteractiveInkFeatureFactory? splashFactory,
  })

参考链接