Material 组件库中提供了多种按钮组件如ElevatedButton
、TextButton
、OutlineButton
等,它们都是集成于ButtonStyleButton
,所以他们大多数属性都和ButtonStyleButton
一样。在介绍各个按钮时我们先介绍其默认外观,而按钮的外观大都可以通过属性来自定义,我们在后面统一介绍这些属性。另外,所有 Material 库中的按钮都有如下相同点:
- 按下时都会有“水波动画”(又称“涟漪动画”,就是点击时按钮上会出现水波扩散的动画)。
- 有一个
onPressed
属性来设置点击回调,当按钮按下时会执行该回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。
ElevatedButton
ElevatedButton(onPressed: (){}, child: const Text("ElevatedButton")),
TextButton
TextButton(onPressed: (){}, child: const Text("TextButton")),
OutlinedButton
OutlinedButton(onPressed: (){}, child: const Text("OutlinedButton")),
IconButton
IconButton(onPressed: (){}, icon: const Icon(Icons.subdirectory_arrow_right)),
Button 的 属性 以ElevatedButton为例
const ElevatedButton({
super.key,
required super.onPressed, // 单击事件
super.onLongPress, // 长按事件
super.onHover, // 鼠标滑入
super.onFocusChange, // 焦点
super.style, // 样式 ButtonStyle 或 ElevatedButton.styleFrom
super.focusNode, //
super.autofocus = false, //
super.clipBehavior = Clip.none, //
super.statesController, //
required super.child, // 可以放置 Widget
});
ButtonStyle styleFrom
static ButtonStyle styleFrom({
Color? foregroundColor, // 前景色(文本颜色)
Color? backgroundColor, // 背景色
//onPressed: null, onLongPress: null, 两个都等于null时 表示禁用button
Color? disabledForegroundColor, // 禁用时前景色(文本颜色)
Color? disabledBackgroundColor,// 禁用时背景色
Color? shadowColor, // 阴影色
Color? surfaceTintColor, // 表面色调颜色 有关详细信息,请参见[Material.surfaceTintColor]。
double? elevation, // 模拟物理深度 就是阴影浅重
TextStyle? textStyle, // 文本样式 TextStyle
EdgeInsetsGeometry? padding, // 内容边距
Size? minimumSize, // 最小尺寸
Size? fixedSize, // 按钮尺寸
Size? maximumSize, // 最大尺寸
BorderSide
BorderSide? side, // 边框样式
const BorderSide(
width: 2, // 粗细
color: Colors.blue, 颜色
style: BorderStyle.solid, // BorderStyle.solid 实线 BorderStyle.none // 没有线
strokeAlign: StrokeAlign.inside // inside, 边框在内部 center, 边框在中间,一半一半 outside,边框在外部
)
OutlinedBorder
OutlinedBorder? shape, // 按钮形状
// shape1 一个 有楞有角的shape
// -----------------------
// BeveledRectangleBorder(
// borderRadius: BorderRadius.circular(20.0),
// side: BorderSide(
// style: BorderStyle.none,
// )
// )
// -----------------------
// shape2 一个 圆形的shape
// -----------------------
// const CircleBorder(
// side: BorderSide(
// //设置 界面效果
// color: Colors.brown,
// width: 3.0,
// style: BorderStyle.solid,
// ),
// ),
// )
// -----------------------
// shape3 一个 类似足球场的shape 圆角不能调 ,最大圆角显示
// -----------------------
// StadiumBorder(side: BorderSide(
// style: BorderStyle.solid,
// color: Color(0xffFF7F24),
// )),
// -----------------------
// shape4 一个 可调节圆角大小的shape
// -----------------------
// RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0))
// -----------------------
其余一些属性
MouseCursor? enabledMouseCursor, //桌面端鼠标样式
MouseCursor? disabledMouseCursor, //禁用时桌面端鼠标样式
VisualDensity? visualDensity, //视觉密度
MaterialTapTargetSize? tapTargetSize, // 响应触摸的区域
Duration? animationDuration, //[shape]和[elevation]的动画更改的持续时间。
bool? enableFeedback, //是否启用反馈,如长按震动
AlignmentGeometry? alignment, // 子组件区域中对齐方式
InteractiveInkFeatureFactory? splashFactory, NoSplash.splashFactory, // 没有水波纹效果
@Deprecated(
'Use backgroundColor instead. '
'This feature was deprecated after v3.1.0.'
)
Color? primary,
@Deprecated(
'Use foregroundColor instead. '
'This feature was deprecated after v3.1.0.'
)
Color? onPrimary,
@Deprecated(
'Use disabledForegroundColor and disabledBackgroundColor instead. '
'This feature was deprecated after v3.1.0.'
)
Color? onSurface,
})
设置 button的属性
方法1 style: ElevatedButton.styleFrom
禁用时的显示 点击事件为null 时 就是禁用状态
ElevatedButton(
child: const Text("normal"),
style: ElevatedButton.styleFrom(
// splashFactory: NoSplash.splashFactory, // 没有水波纹效果
backgroundColor: const Color(0xff000000), // 背景黑色
foregroundColor: const Color(0xffffffff), // 文字白色
disabledForegroundColor: const Color(0xffffff00), // 禁用时前景色
disabledBackgroundColor: const Color(0xff1100ff),//禁用时 背景色
shadowColor:const Color(0xffff0000),//阴影颜色
elevation: 20, //阴影高度
maximumSize: const Size(2000, 100),//最大尺寸
textStyle: const TextStyle(
fontSize: 40 // 文字大小
),
padding: const EdgeInsets.only( // 边距
left: 20.0,top: 10.0, right: 20.0,bottom: 10.0
),
side: const BorderSide( //边框
width: 2,
color: Colors.blue,
style: BorderStyle.none,
strokeAlign: StrokeAlign.inside //
),
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)) // 可调节圆角的shape
shape:BeveledRectangleBorder( // 棱形shape
borderRadius: BorderRadius.circular(20.0),
side: const BorderSide(
style: BorderStyle.none,
)),
),
onPressed: (){}, // 为null 时 显示为蓝色的图
// onLongPress: null, // 长按事件
),
方法2 MaterialStatePropertyAll , MaterialStateProperty.resolveWith
ElevatedButton(
child: const Text("normal"),
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll<Color>(Colors.green),
fixedSize: const MaterialStatePropertyAll<Size>(Size(100,100)),
foregroundColor: MaterialStateProperty.resolveWith((states) {
return states.contains(MaterialState.pressed)
? Colors.blue
: Colors.red;
}),
shape: MaterialStateProperty.all(
const CircleBorder( // 圆形shape
side: BorderSide(
//设置 界面效果
color: Colors.brown,
width: 3.0,
style: BorderStyle.solid,
),
),
)
),
onPressed: () {},
),
TextButton(
child: const Text("normal"),
onPressed: () {},
style: const ButtonStyle(
shape: MaterialStatePropertyAll<OutlinedBorder>(
StadiumBorder(side: BorderSide(
style: BorderStyle.solid,
color: Color(0xffFF7F24),
)),
)
),
),
MaterialStateProperty
在 MaterialStateProperty 里有一个 MaterialState 枚举,它主要包含了
disabled:当控件或元素不能交互性时
hovered:鼠标交互悬停时
focused: 在键盘交互中突出显示
selected:例如 check box 的选定状态
pressed:通过鼠标、键盘或者触摸等方法发起的轻击或点击
dragged:用户长按并移动控件时
error:错误状态下,比如 TextField 的 Error
static MaterialStateProperty<T> resolveWith<T>(MaterialPropertyResolver<T> callback) => _MaterialStatePropertyWith<T>(callback);
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.pressed)) {
return Colors.red;
}
return Colors.blue;
})),
static MaterialStateProperty<T> all<T>(T value) => MaterialStatePropertyAll<T>(value);
elevation: MaterialStateProperty.all(20),
MaterialStatePropertyAll
backgroundColor: MaterialStatePropertyAll<Color>(Colors.green),
fixedSize: const MaterialStatePropertyAll<Size>(Size(100,100)),
其他的方式没怎么研究
其余样式button样式
Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
OutlinedButton(
child: const Text("RoundedRectangleBorder"),
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0))
),
onPressed: () {
print("点击了按钮");
},
),
IconButton(
icon: const Icon(Icons.thumb_up),
onPressed: () {},
)
],
),
Row(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 16.0, color: Colors.lightBlue.shade50),
bottom: BorderSide(width: 16.0, color: Colors.lightBlue.shade900),
),
),
child: OutlinedButton(
child: const Text("normal"),
onPressed: () {
print("点击了按钮");
},
),
)
],
), Row(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: 16.0, color: Colors.lightBlue.shade50),
bottom: BorderSide(width: 16.0, color: Colors.lightBlue.shade900),
),
),
child: OutlinedButton(
child: const Text("normal"),
onPressed: () {
print("点击了按钮");
},
),
)
],
),
Row(
children: [
Container(
margin: const EdgeInsets.only(
right: 20,
left: 20,
top: 14),
alignment: Alignment.center,
color: Colors.blue,
child: SizedBox(
width: 200,//double.infinity
height: 50,
child: ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
backgroundColor: MaterialStateProperty.all(Color(0xffFCB605)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35))),
),
onPressed: (){},
child: const Text(
'登录',
style: TextStyle(color: Colors.red, fontSize: 15),
),
),
),
)
],
),