[toc]
Flutter框架提供了三個(gè)Button組件,分別是 TextButton、OutlinedButton 和 ElevatedButton。這三個(gè)組件都是以 ButtonStyleButton 為父類,所以源碼詳讀從這個(gè)類開始。
另外,因?yàn)锽uttonStyleButton中用到了_ButtonStyleState、ButtonStyle 和MaterialStateProperty,所以也會閱讀到這三個(gè)類。
ButtonStyleButton
概述
這個(gè)類本身是一個(gè)抽象類,繼承了StatefulWideget,并重寫了 createState 方法,有一個(gè)與此類對應(yīng)的State類(_ButtonStyleState)。三個(gè)子類也都是使用從這里繼承的createState方法和State類。
1. 構(gòu)造器
提供了常量構(gòu)造器,從而其子類也可以提供常量構(gòu)造器。
2. 屬性
// 這兩個(gè)屬性分別是短按和長按的回調(diào)函數(shù)
final VoidCallback? onPressed;
final VoidCallback? onLongPress;
// 如果同時(shí)為空,那么按鈕將處于禁用狀態(tài)
// 禁用狀態(tài)屬性 enable 也就是通過這兩個(gè)回調(diào)為空判斷的
bool get enabled => onPressed != null || onLongPress != null;
// 當(dāng)pointer進(jìn)入或退出按鈕響應(yīng)區(qū)域時(shí)被調(diào)用
// 進(jìn)入時(shí)參數(shù)為true,退出時(shí)參數(shù)為false
final ValueChanged<bool>? onHover;
// 當(dāng)焦點(diǎn)發(fā)生變化時(shí)調(diào)用
// 獲取到焦點(diǎn)為true,失去焦點(diǎn)為false
final ValueChanged<bool>? onFocusChange;
// 用來自定義按鈕的樣式
// style 對象中非空的屬性會覆寫
// themeStyleOf 和 defaultStyleOf 這兩個(gè)方法所提供的對象的屬性
// 同樣的覆蓋邏輯適用于style中MaterialStateProperty類型屬性的屬性
final ButtonStyle? style;
// 默認(rèn)為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.方法
// 非抽象子類應(yīng)該返回一個(gè)屬性非空的ButtonStyle對象,并且對象的MaterialStateProperty類型屬性的屬性也不應(yīng)該是null
// 相同的屬性會被themeStyleOf返回的ButtonStyle對象所覆蓋
@protected
ButtonStyle defaultStyleOf(BuildContext context);
// 會被style屬性覆蓋
// 非抽象子類的返回值應(yīng)該是最近的子類特定繼承的主題
@protected
ButtonStyle? themeStyleOf(BuildContext context);
// 覆寫 StatefulWidget 的createState,框架提供的三個(gè)子類是都是繼承了這個(gè)實(shí)現(xiàn)
@override
State<ButtonStyleButton> createState() => _ButtonStyleState();
// 用于debug和profile模式下程序診斷的
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
// 靜態(tài)方法
static MaterialStateProperty<T>? allOrNull<T>(T? value) => value == null ? null : MaterialStateProperty.all<T>(value);
// 靜態(tài)方法
static EdgeInsetsGeometry scaledPadding(
EdgeInsetsGeometry geometry1x,
EdgeInsetsGeometry geometry2x,
EdgeInsetsGeometry geometry3x,
double textScaleFactor,) {