Material 组件库中有多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们的父类是于ButtonStyleButton。
基本的按钮特点:
1.按下时都会有"水波文动画"。
2.onPressed属性设置点击回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。
ElevatedButton
简单实现
Dart
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,
});
Dart
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方法设置按钮的样式,包括背景色、文本颜色、阴影效果、最小宽度和形状等。
Dart
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
Dart
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边距
Dart
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,
))
],
),
),
);
}
}

水平填充满
Dart
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
Dart
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,
});
简单实现
Dart
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))才会生效。
Dart
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"))
],
),
),
);
}
}

设置按钮按下时,获取焦点时、默认状态时的颜色
Dart
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
Dart
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 配置的样式
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;
}),
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
Dart
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,
});
简单实现
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"),
OutlinedButton(
onPressed: () {
print('OutlinedButton clicked');
},
child: Text('Click OutlinedButton'))
],
),
),
);
}
}
Dart
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
长按事件
Dart
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 检测到的手势是否应提供声音和/或触觉反馈。
设置字体大小(注意:这里设置颜色不会生效)
Dart
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30))
),
backgroundColor 背景色
Dart
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
)

foregroundColor 字体颜色
Dart
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
),

overlayColor 高亮色,按钮处于focused, hovered, pressed时的颜色
Dart
style: ButtonStyle(
textStyle: WidgetStateProperty.all(TextStyle(fontSize: 30)),
backgroundColor: WidgetStateProperty.all(Colors.red),
foregroundColor: WidgetStateProperty.all(Colors.yellow),
overlayColor: WidgetStateProperty.all(Colors.blue),
)
side 边框
Dart
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 阴影值
Dart
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 形状
棱形
Dart
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))),
)

圆角弧度
Dart
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,
)))),



