[toc]
Flutter框架提供了三个Button组件,分别是 TextButton、OutlinedButton 和 ElevatedButton。这三个组件都是以 ButtonStyleButton 为父类,所以源码详读从这个类开始。
另外,因为ButtonStyleButton中用到了_ButtonStyleState、ButtonStyle 和MaterialStateProperty,所以也会阅读到这三个类。
ButtonStyleButton
概述
这个类本身是一个抽象类,继承了StatefulWideget,并重写了 createState 方法,有一个与此类对应的State类(_ButtonStyleState)。三个子类也都是使用从这里继承的createState方法和State类。
1. 构造器
提供了常量构造器,从而其子类也可以提供常量构造器。
2. 属性
// 这两个属性分别是短按和长按的回调函数
final VoidCallback? onPressed;
final VoidCallback? onLongPress;
// 如果同时为空,那么按钮将处于禁用状态
// 禁用状态属性 enable 也就是通过这两个回调为空判断的
bool get enabled => onPressed != null || onLongPress != null;
// 当pointer进入或退出按钮响应区域时被调用
// 进入时参数为true,退出时参数为false
final ValueChanged<bool>? onHover;
// 当焦点发生变化时调用
// 获取到焦点为true,失去焦点为false
final ValueChanged<bool>? onFocusChange;
// 用来自定义按钮的样式
// style 对象中非空的属性会覆写
// themeStyleOf 和 defaultStyleOf 这两个方法所提供的对象的属性
// 同样的覆盖逻辑适用于style中MaterialStateProperty类型属性的属性
final ButtonStyle? style;
// 默认为Clip.none
final Clip clipBehavior;
// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;
// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus;
// Typically the button's label.
final Widget? child;
3.方法
// 非抽象子类应该返回一个属性非空的ButtonStyle对象,并且对象的MaterialStateProperty类型属性的属性也不应该是null
// 相同的属性会被themeStyleOf返回的ButtonStyle对象所覆盖
@protected
ButtonStyle defaultStyleOf(BuildContext context);
// 会被style属性覆盖
// 非抽象子类的返回值应该是最近的子类特定继承的主题
@protected
ButtonStyle? themeStyleOf(BuildContext context);
// 覆写 StatefulWidget 的createState,框架提供的三个子类是都是继承了这个实现
@override
State<ButtonStyleButton> createState() => _ButtonStyleState();
// 用于debug和profile模式下程序诊断的
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
// 静态方法
static MaterialStateProperty<T>? allOrNull<T>(T? value) => value == null ? null : MaterialStateProperty.all<T>(value);
// 静态方法
static EdgeInsetsGeometry scaledPadding(
EdgeInsetsGeometry geometry1x,
EdgeInsetsGeometry geometry2x,
EdgeInsetsGeometry geometry3x,
double textScaleFactor,) {