Material 组件库中提供了多种按钮组件,比如 RaisedButton、FlatButton、OutlineButton、DropdownButton、RawMaterialButton、PopupMenuButton、IconButton、BackButton、CloseButton、ButtonBar、ToggleButtons等。它们都是直接或间接对RawMaterialButton
组件的包装定制,所以他们大多数属性都和RawMaterialButton
一样。在介绍各个按钮时我们先介绍其默认外观,而按钮的外观大都可以通过属性来自定义,我们在后面统一介绍这些属性。
另外,所有Material 库中的按钮都有如下相同点:
- 按下时都会有“水波动画”(又称“涟漪动画”,就是点击时按钮上会出现水波荡漾的动画)。
- 有一个
onPressed
属性来设置点击回调,当按钮按下时会执行该回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。
按钮常用API
按钮外观可以通过其属性来定义,不同按钮属性大同小异,我们以 RaisedButton
为例,介绍一下常见的按钮属性,详细的信息可以查看API文档。
RaisedButton({
Key key,
//点击回调,传null 表示按钮禁用,会显示禁用相关样式
@required VoidCallback onPressed,
//长按回调
VoidCallback onLongPress,
//按钮高亮变化回调,当点击或者按住按钮时,按钮出现水波纹效果,水波纹变化时就是高亮状态。
ValueChanged<bool> onHighlightChanged,
MouseCursor mouseCursor,
ButtonTextTheme textTheme, //ButtonTextTheme.primary, //前景色 normal accent primary
Color textColor, //文本颜色
Color disabledTextColor, //禁用时文字颜色
Color color, //背景色
Color disabledColor, //禁用时背景色
Color focusColor, //聚焦时背景色
Color hoverColor, //hover时背景色
Color highlightColor, //高亮时背景色,即按钮按下时的背景颜色
Color splashColor, //水波纹颜色,按下时会有水波纹效果
Brightness colorBrightness, //按钮主题,默认是浅色主题 dark light
double elevation, //阴影的范围,值越大阴影范围越大
double focusElevation,
double hoverElevation,
double highlightElevation, //高亮阴影
double disabledElevation, //禁用状态阴影
EdgeInsetsGeometry padding, //内边距
VisualDensity visualDensity, //视觉偏移 范围[-4.0, 4.0]
ShapeBorder shape, //设置按钮的形状
Clip clipBehavior = Clip.none,
FocusNode focusNode,
bool autofocus = false,
MaterialTapTargetSize materialTapTargetSize, //默认边距padded 去掉默认边距shrinkWrap
Duration animationDuration,
Widget child,
})
示例:定义一个背景蓝色,圆角按钮,点击时蓝色加重
FlatButton(
color: Colors.blue,
highlightColor: Colors.blue[700],
colorBrightness: Brightness.dark,
splashColor: Colors.grey,
child: Text("Submit"),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
onPressed: () {},
)
主要通过shape
来指定其外形为一个圆角矩形。因为按钮背景是蓝色(深色),我们需要指定按钮主题colorBrightness
为Brightness.dark
,这是为了保证按钮文字颜色为浅色。
Flutter 中没有提供去除背景的设置,假若我们需要去除背景,则可以通过将背景颜色设置为全透明来实现。对应上面的代码,便是将 color: Colors.blue
替换为 color: Color(0x000000)
。
我们也可以为这个按钮加上阴影,让它显得有质感。只需要将上面的FlatButton
换成RaisedButton
就行,其它代码不用改,换了之后的效果:
常规按钮
RaisedButton 凸起按钮
https://api.flutter.dev/flutter/material/RaisedButton-class.html
即”漂浮”按钮,它默认带有阴影和灰色背景。按下后,阴影会变大。
Column(
children: [
RaisedButton(
child: Text('按钮'),
onPressed: (){},
),
// 有宽高的按钮
Container(
width: 200.0,
height: 60.0,
child: RaisedButton(
child: Text('按钮'),
onPressed: (){},
),
),
],
);
FlatButton 扁平按钮
https://api.flutter.dev/flutter/material/FlatButton-class.html
扁平按钮,默认背景透明并不带阴影。按下后,会有背景色。
FlatButton(
child: Text('按钮'),
onPressed: () {},
),
OutlineButton 幽灵按钮
默认有一个边框,不带阴影且背景透明。按下后,边框颜色会变亮、同时出现背景和阴影(较弱)。
OutlineButton(
child: Text('按钮'),
onPressed: () {},
),
IconButton 图标按钮
https://api.flutter.dev/flutter/material/IconButton-class.html
是一个可点击的Icon,不包括文字,默认没有背景,点击后会出现背景。
IconButton(
icon: Icon(Icons.access_alarm),
onPressed: () {},
iconSize: 24.0, //图标大小
tooltip: '提示文案',
),
带图标的文字按钮
RaisedButton
、FlatButton
、OutlineButton
都有一个icon
构造函数,通过它可以轻松创建带图标的按钮。
RaisedButton.icon(
icon: Icon(Icons.send),
label: Text("发送"),
onPressed: () {},
),
OutlineButton.icon(
icon: Icon(Icons.add),
label: Text("添加"),
onPressed: () {},
),
FlatButton.icon(
icon: Icon(Icons.info),
label: Text("详情"),
onPressed: () {},
),
FloatingActionButton
https://api.flutter.dev/flutter/material/FloatingActionButton-class.html
一个圆形图标按钮,它悬停在内容之上,以展示应用程序中的主要动作。FloatingActionButton通常用于Scaffold.floatingActionButton字段。
Scaffold(
appBar: AppBar(title: Text('我是导航标题')),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add, size: 34),
onPressed: () {},
backgroundColor: Colors.yellow,
foregroundColor: Colors.black,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, //悬浮位置
);
按钮内通过Builder组件 获取按钮位置的context
GlobalKey _formKey = GlobalKey();
Form(
key: _formKey, //设置globalKey,用于后面获取FromState
child: RaisedButton(
child: Text('登录'),
onPressed: () {
//这里获取的context是根context,不能通过这个context获取FormState
print(Form.of(context)); //null
// 通过_formKey.currentState 获取FormState后,
// 调用validate()方法校验用户名密码是否合法,校验通过后再提交数据。
if ((_formKey.currentState as FormState).validate()) {
//验证通过提交数据
}
},
),
)
Form(
key: _formKey,
// 通过Builder来获取按钮位置所在widget树的真正context(Element)
child: Builder(
builder: (context){
return RaisedButton(
child: Text('登录'),
onPressed: () {
//由于本widget也是Form的子代widget,所以可以通过下面方式获取FormState
if(Form.of(context).validate()){
//验证通过提交数据
}
},
);
},
),
)
ButtonBar 按钮组
https://api.flutter.dev/flutter/material/ButtonBar-class.html
ButtonBar({
Key key,
this.alignment, //对齐方式 alignment: MainAxisAlignment.start,
this.mainAxisSize, //min max
this.buttonTextTheme, //主题色
this.buttonMinWidth, //按钮最小宽度
this.buttonHeight, //按钮高度
this.buttonPadding, //constrained padded
this.buttonAlignedDropdown,
this.layoutBehavior, //constrained padded
this.overflowDirection, //down up
this.overflowButtonSpacing,
this.children = const <Widget>[],
})
示例
ButtonBar(
alignment: MainAxisAlignment.start,
// mainAxisSize: MainAxisSize.min, //min max
buttonTextTheme: ButtonTextTheme.accent,
// buttonMinWidth: 200.0,
// buttonHeight: 200.0,
// buttonPadding: EdgeInsets.all(20.0),
// buttonAlignedDropdown: true,
// layoutBehavior: ButtonBarLayoutBehavior.padded, //constrained padded
// overflowDirection: VerticalDirection.up, //down up
// overflowButtonSpacing: 1.0,
children: [
RaisedButton(child: Text('按钮1'), onPressed: () {}),
RaisedButton(child: Text('按钮2'), onPressed: () {}),
RaisedButton(child: Text('按钮3'), onPressed: () {}),
RaisedButton(child: Text('按钮4'), onPressed: () {}),
],
),
自定义按钮
lib/coms/base/buttons/MyButton.dart
import "package:flutter/material.dart";
class MyButton extends StatelessWidget {
final text;
final onPressed;
final width;
final height;
const MyButton({
key,
this.text = '',
this.onPressed = null,
this.width = 80.0,
this.height = 30.0,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: this.width,
height: this.height,
child: RaisedButton(
child: Text(this.text),
onPressed: this.onPressed,
),
);
}
}
使用
import "package:app1/coms/base/buttons/MyButton.dart";
//...
MyButton(
text: '按钮1',
onPressed: () {},
),