一、源码解读
// ElevatedButton 继承于 ButtonStyleButton
class ElevatedButton extends ButtonStyleButton {
// 创建一个按钮
const ElevatedButton({
Key? key, // 标识
required VoidCallback? onPressed, // 按钮的按压事件的回调方法
VoidCallback? onLongPress, // 按钮长按事件回调方法
ValueChanged<bool>? onHover, // 鼠标悬停事件的回调方法
ValueChanged<bool>? onFocusChange, // 按钮焦点的变化回调事件方法
ButtonStyle? style, // 按钮的样式
FocusNode? focusNode, // 按钮的焦点
bool autofocus = false, // 是否自动获取焦点
Clip clipBehavior = Clip.none, // 按钮的裁剪形式
required Widget? child, // 按钮的子组件对象
}) : super(
key: key,
onPressed: onPressed,
onLongPress: onLongPress,
onHover: onHover,
onFocusChange: onFocusChange,
style: style,
focusNode: focusNode,
autofocus: autofocus,
clipBehavior: clipBehavior,
child: child,
);
/// 生成一个图标和文字一排的按钮
factory ElevatedButton.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, // 按钮的文字
}) = _ElevatedButtonWithIcon;
// 在给定值得情况下,便捷获取按钮样式的方法
static ButtonStyle styleFrom({
Color? primary, // 按钮的基本颜色
Color? onPrimary, // 按钮获取焦点的基本颜色
Color? onSurface, // 按钮获取焦点表面颜色
Color? shadowColor, // 按钮阴影颜色
double? elevation, // 阴影 Z 轴大小设置
TextStyle? textStyle, // 按钮文字样式
EdgeInsetsGeometry? padding, // 按钮的内边距大小
Size? minimumSize, // 按钮的最小尺寸
Size? fixedSize, // 按钮的固定尺寸
Size? maximumSize, // 按钮的最大尺寸
BorderSide? side, // 按钮的边框边对象
OutlinedBorder? shape, // 按钮轮廓边框样式
MouseCursor? enabledMouseCursor, // 启用鼠标光标
MouseCursor? disabledMouseCursor, // 关闭鼠标光标
VisualDensity? visualDensity, // 按钮的视觉密度
MaterialTapTargetSize? tapTargetSize, // 按钮触控区域大小
Duration? animationDuration, // 动画时长
bool? enableFeedback, // 是否启动反馈
AlignmentGeometry? alignment, // 按钮的子组件的位置
InteractiveInkFeatureFactory? splashFactory, // 水波纹效果的设置
}) {
// 按钮的背景色
final MaterialStateProperty<Color?>? backgroundColor = (onSurface == null && primary == null)
? null
: _ElevatedButtonDefaultBackground(primary, onSurface);
// 按钮的前景色
final MaterialStateProperty<Color?>? foregroundColor = (onSurface == null && onPrimary == null)
? null
: _ElevatedButtonDefaultForeground(onPrimary, onSurface);
// 按钮的叠加色
final MaterialStateProperty<Color?>? overlayColor = (onPrimary == null)
? null
: _ElevatedButtonDefaultOverlay(onPrimary);
// 按钮 Z 轴阴影大小
final MaterialStateProperty<double>? elevationValue = (elevation == null)
? null
: _ElevatedButtonDefaultElevation(elevation);
// 光标的状态
final MaterialStateProperty<MouseCursor?>? mouseCursor = (enabledMouseCursor == null && disabledMouseCursor == null)
? null
: _ElevatedButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor);
return ButtonStyle(
textStyle: MaterialStateProperty.all<TextStyle?>(textStyle),
backgroundColor: backgroundColor,
foregroundColor: foregroundColor,
overlayColor: overlayColor,
shadowColor: ButtonStyleButton.allOrNull<Color>(shadowColor),
elevation: elevationValue,
padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
minimumSize: ButtonStyleButton.allOrNull<Size>(minimumSize),
fixedSize: ButtonStyleButton.allOrNull<Size>(fixedSize),
maximumSize: ButtonStyleButton.allOrNull<Size>(maximumSize),
side: ButtonStyleButton.allOrNull<BorderSide>(side),
shape: ButtonStyleButton.allOrNull<OutlinedBorder>(shape),
mouseCursor: mouseCursor,
visualDensity: visualDensity,
tapTargetSize: tapTargetSize,
animationDuration: animationDuration,
enableFeedback: enableFeedback,
alignment: alignment,
splashFactory: splashFactory,
);
}
/// 定义按钮的默认外观,重写 ButtonStyleButton 的 defaultStyleOf方法
@override
ButtonStyle defaultStyleOf(BuildContext context) {
// 获取系统主题
final ThemeData theme = Theme.of(context);
// 获取系统主题颜色方案
final ColorScheme colorScheme = theme.colorScheme;
// 按钮内边距缩放填充
final EdgeInsetsGeometry scaledPadding = ButtonStyleButton.scaledPadding(
const EdgeInsets.symmetric(horizontal: 16),
const EdgeInsets.symmetric(horizontal: 8),
const EdgeInsets.symmetric(horizontal: 4),
MediaQuery.maybeOf(context)?.textScaleFactor ?? 1, // 系统文字缩放因子
);
return styleFrom(
primary: colorScheme.primary,
onPrimary: colorScheme.onPrimary,
onSurface: colorScheme.onSurface,
shadowColor: theme.shadowColor,
elevation: 2,
textStyle: theme.textTheme.button,
padding: scaledPadding,
minimumSize: const Size(64, 36),
maximumSize: Size.infinite,
// 圆角为4的矩形
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4))),
enabledMouseCursor: SystemMouseCursors.click, // 启用
disabledMouseCursor: SystemMouseCursors.forbidden, // 禁用
visualDensity: theme.visualDensity,
tapTargetSize: theme.materialTapTargetSize,
animationDuration: kThemeChangeDuration,
enableFeedback: true,
alignment: Alignment.center,
splashFactory: InkRipple.splashFactory,
);
}
/// 获取 ElevatedButtonTheme 主题的样式
@override
ButtonStyle? themeStyleOf(BuildContext context) {
return ElevatedButtonTheme.of(context).style;
}
}
二、实例
// 基本按钮
ElevatedButton(
onPressed: () {},
child: Text('ElevatedButton 测试'),
)
// 图片 + 文字按钮 或者 文字 + 图片
ElevatedButton.icon(
onPressed: () {},
icon: Icon(Icons.abc),
label: Text('ElevatedButton 测试'),
)