Material 组件库中有多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们的父类是于ButtonStyleButton。
基本的按钮特点:
1.按下时都会有“水波文动画”。
2.onPressed属性设置点击回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。
ElevatedButton
简单实现
const ElevatedButton({
super.key,
required super.onPressed,
super.onLongPress,
super.onHover,
super.onFocusChange,
super.style,
super.focusNode,
super.autofocus = false,
super.clipBehavior,
super.statesController,
required super.child,
super.iconAlignment,
});
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
ElevatedButton(
onPressed: () {
print('ElevatedButton clicked');
},
child: Text("Click ElevatedButton"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
elevation: 10,
minimumSize: Size(150, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10))),
)
],
),
),
);
}
}
对上面的属性做简单介绍:
- child: Text("Click ElevatedButton")设置按钮显示的文本为“Click ElevatedButton”。
- onPressed:设置按钮点击事件。
- style:使用ElevatedButton.styleFrom方法设置按钮的样式,包括背景色、文本颜色、阴影效果、最小宽度和形状等。
2024-09-07 15:44:54.993 12985-13050 flutter I ElevatedButton clicked
2024-09-07 15:44:56.418 12985-13050 flutter I ElevatedButton clicked
2024-09-07 15:44:57.601 12985-13050 flutter I ElevatedButton clicked
2024-09-07 15:44:58.044 12985-13050 flutter I ElevatedButton clicked
2024-09-07 15:47:37.981 12985-13050 flutter I ElevatedButton clicked
static ButtonStyle styleFrom({
Color? foregroundColor,
Color? backgroundColor,
Color? disabledForegroundColor,
Color? disabledBackgroundColor,
Color? shadowColor,
Color? surfaceTintColor,
Color? iconColor,
Color? disabledIconColor,
Color? overlayColor,
double? elevation,
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,
ButtonLayerBuilder? backgroundBuilder,
ButtonLayerBuilder? foregroundBuilder,
})
去除去掉ElevatedButton边距
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
ElevatedButton(
onPressed: () {
print('ElevatedButton clicked');
},
child: Text("Click ElevatedButton"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
elevation: 10,
minimumSize: Size.zero,
padding: EdgeInsets.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
))
],
),
),
);
}
}
水平填充满
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
ElevatedButton(
onPressed: () {
print('ElevatedButton clicked');
},
child: Text("Click ElevatedButton"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
elevation: 10,
minimumSize: Size(double.infinity, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10))),
)
],
),
),
);
}
}
TextButton
const TextButton({
super.key,
required super.onPressed,
super.onLongPress,
super.onHover,
super.onFocusChange,
super.style,
super.focusNode,
super.autofocus = false,
super.clipBehavior,
super.statesController,
super.isSemanticButton,
required Widget super.child,
super.iconAlignment,
});
简单实现
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
TextButton(
onPressed: () {
print('TextButton clicked');
},
autofocus: false,
style: ButtonStyle(
textStyle: WidgetStateProperty.all(
TextStyle(fontSize: 20, color: Colors.red))),
child: Text("Click TextButton"))
],
),
),
);
}
}
注意:上面通过 textStyle: WidgetStateProperty.all(TextStyle(fontSize: 20, color: Colors.red))来设置按钮字体颜色是无效的,发现颜色还是蓝色,而不是红色。
通过foregroundColor:WidgetStateProperty.all(Colors.yellow))才会生效。
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
TextButton(
onPressed: () {
print('TextButton clicked');
},
autofocus: false,
style: ButtonStyle(
textStyle: WidgetStateProperty.all(
TextStyle(fontSize: 20, color: Colors.red)),
foregroundColor:
WidgetStateProperty.all(Colors.yellow)),
child: Text("Click TextButton"))
],
),
),
);
}
}
设置按钮按下时,获取焦点时、默认状态时的颜色
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
TextButton(
onPressed: () {
print('TextButton clicked');
},
autofocus: false,
style: ButtonStyle(
textStyle: WidgetStateProperty.all(
const TextStyle(fontSize: 20, color: Colors.red)),
foregroundColor: WidgetStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused) &&
!states.contains(MaterialState.pressed)) {
//获取焦点时的颜色
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
//按下时的颜色
return Colors.yellow;
}
//默认状态使用灰色
return Colors.black;
},
),
),
// foregroundColor:
// WidgetStateProperty.all(Colors.yellow)),
child: Text("Click TextButton"))
],
),
),
);
设置背景颜色 backgroundColor
import 'package:flutter/material.dart';
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
TextButton(
onPressed: () {
print('TextButton clicked');
},
autofocus: false,
style: ButtonStyle(
textStyle: WidgetStateProperty.all(
const TextStyle(fontSize: 20, color: Colors.red)),
foregroundColor: WidgetStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused) &&
!states.contains(MaterialState.pressed)) {
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
return Colors.yellow;
}
return Colors.black;
},
),
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return Colors.red;
}
return null;
}),
),
// foregroundColor:
// WidgetStateProperty.all(Colors.yellow)),
child: Text("Click TextButton"))
],
),
)
其他设置
overlayColor: 设置水波纹颜色。
padding: 设置按钮内边距。
minimumSize: 设置按钮的大小。
side: 设置边框。
shape: 外边框装饰 会覆盖 side 配置的样式
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
TextButton(
onPressed: () {
print('TextButton clicked');
},
autofocus: false,
style: ButtonStyle(
textStyle: WidgetStateProperty.all(
const TextStyle(fontSize: 20, color: Colors.red)),
foregroundColor: WidgetStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused) &&
!states.contains(MaterialState.pressed)) {
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
return Colors.yellow;
}
return Colors.black;
},
),
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return Colors.red;
}
return null;
}),
overlayColor: WidgetStateProperty.all(Colors.red),
padding: WidgetStateProperty.all(EdgeInsets.all(10)),
minimumSize: WidgetStateProperty.all(Size(300, 100)),
side: WidgetStateProperty.all(
BorderSide(color: Colors.blue, width: 1)),
shape: WidgetStateProperty.all(StadiumBorder()),
),
// foregroundColor:
// WidgetStateProperty.all(Colors.yellow)),
child: Text("Click TextButton"))
],
),
),
);
}
}
OutlinedButton
const OutlinedButton({
super.key,
required super.onPressed,
super.onLongPress,
super.onHover,
super.onFocusChange,
super.style,
super.focusNode,
super.autofocus = false,
super.clipBehavior,
super.statesController,
required super.child,
super.iconAlignment,
});
简单实现
class ButtonWidgetPage extends StatelessWidget {
const ButtonWidgetPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Button Demo"),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("TEST Button"),
OutlinedButton(
onPressed: () {
print('OutlinedButton clicked');
},
child: Text('Click OutlinedButton'))
],
),
),
);
}
}
2024-09-08 11:03:01.333 4839-4871 flutter I OutlinedButton clicked
2024-09-08 11:03:02.027 4839-4871 flutter I OutlinedButton clicked
2024-09-08 11:03:02.352 4839-4871 flutter I OutlinedButton clicked
2024-09-08 11:03:02.547 4839-4871 flutter I OutlinedButton clicked
2024-09-08 11:03:02.709 4839-4871 flutter I OutlinedButton clicked
2024-09-08 11:03:40.339 4839-4871 flutter I OutlinedButton clicked
长按事件
onLongPress: () {
print('OutlinedButton onLongPress');
},
相关属性
textStyle 字体样式
backgroundColor 背景色
foregroundColor 字体颜色
overlayColor 高亮色,按钮处于focused, hovered, pressed时的颜色
shadowColor 阴影颜色
elevation 阴影值
padding padding
minimumSize 最小尺寸
side 边框
shape 形状
mouseCursor 鼠标指针的光标进入或者悬停在此按钮上
visualDensity 按钮布局的紧凑程度
tapTargetSize 响应触摸的区域
animationDuration [shape]和[elevation]的动画更改的持续时间。
enableFeedback 检测到的手势是否应提供声音和/或触觉反馈。
设置字体大小(注意:这里设置颜色不会生效)
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30))
),
backgroundColor 背景色
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
)
foregroundColor 字体颜色
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
),
overlayColor 高亮色,按钮处于focused, hovered, pressed时的颜色
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
)
side 边框
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
side: WidgetStateProperty.all(BorderSide(width: 1,color: Colors.green)),
)
shadowColor 阴影颜色 & elevation 阴影值
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
side: WidgetStateProperty.all(
BorderSide(width: 1, color: Colors.green)),
shadowColor: WidgetStateProperty.all(Colors.black),
elevation: WidgetStateProperty.all(10),
)
shape 形状
棱形
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
side: WidgetStateProperty.all(
BorderSide(width: 1, color: Colors.green)),
shadowColor: WidgetStateProperty.all(Colors.black),
elevation: WidgetStateProperty.all(10),
shape: WidgetStateProperty.all(BeveledRectangleBorder(borderRadius: BorderRadius.circular(10))),
)
圆角弧度
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
side: WidgetStateProperty.all(
BorderSide(width: 1, color: Colors.green)),
shadowColor: WidgetStateProperty.all(Colors.black),
elevation: WidgetStateProperty.all(10),
//shape: WidgetStateProperty.all(BeveledRectangleBorder(borderRadius: BorderRadius.circular(10))),
shape: WidgetStateProperty.all(StadiumBorder(
side: BorderSide(
style: BorderStyle.solid,
color: Colors.blue,
)))),