对话框 Dialog
Dialog:A material design dialog.
与其直接使用Dialog
,Flutter
推荐使用:AlertDialog ,SimpleDialog
看一下Dialog
构造函数参数的作用:
const Dialog({
Key key,
this.backgroundColor,// 背景颜色
this.elevation,// 阴影高度
this.insetAnimationDuration = const Duration(milliseconds: 100),// 弹窗显示的动画持续时间。默认100ms
this.insetAnimationCurve = Curves.decelerate,// 弹窗显示时的动画
this.shape,// dialog 的形状
this.child,
})
AlertDialog
具有标题,内容的提示框,有用户操作。通常与
showDialog
结合使用。
看一下AlertDialog
有哪些参数:
const AlertDialog({
Key key,
this.title,// 标题
this.titlePadding,// 标题内边距,默认为空
this.titleTextStyle,// 标题文字样式
this.content,// 内容
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),// 内容 内边距,不能为空
this.contentTextStyle,// 内容文字样式
this.actions,// 对话框下边的Widget组件集合,如确认、取消按钮
this.backgroundColor,// 背景颜色
this.elevation,// 阴影高度
this.semanticLabel,// 语义标签
this.shape,// dialog 形状
})
看个AlertDialog
的例子:
伪代码实现,点击show dialog
按钮调用_neverSatisfied
显示弹窗:
Future<void> _neverSatisfied(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Rewind and remember'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('You will never be satisfied.'),
Text('You\’re like me. I’m never satisfied.'),
],
),
),
backgroundColor: Colors.red[200],
elevation: 10,
semanticLabel: 'AlertDialog',
// 设置圆角
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Agree'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
SimpleDialog
SimpleDialog
,用于处理内容的滚动,但没有actions
。如果用户取消对话框(例如,通过点击Android
上的“后退”按钮或点击对话框后面的遮罩),则将以空值结束。
查看构造函数中的参数,参数基本和AlertDialog
一致,并且这里默认titlePadding
是有值的:
const SimpleDialog({
Key key,
this.title,
this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
this.children,// 子布局,title 下方的布局,通常是 SimpleDialogOption 列表。
this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),
this.backgroundColor,
this.elevation,
this.semanticLabel,
this.shape,
})
使用示例:
伪代码,点击show SimpleDialog
按钮之后调用_askedToLead
方法显示弹窗:
Future<void> _askedToLead(BuildContext context) async {
switch (await showDialog<Department>(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Select assignment'),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
// 传递点击的值:Department.treasury
Navigator.pop(context, Department.treasury);
},
child: const Text('Treasury department'),
),
SimpleDialogOption(
onPressed: () {
// 传递点击的值:Department.state
Navigator.pop(context, Department.state);
},
child: const Text('State department'),
),
],
);
})) {
case Department.treasury:
// 接收到点击的值
print('Department.treasury');
break;
case Department.state:
// 接收到点击的值
print('Department.state');
break;
}
}
enum Department {
treasury, // Error
state, // Error
}
列表框
如果内容过多,超过了显示区域,这时候可以使用
SingleChildScrollView
来作为child
,避免超出区域的状况。
伪代码实现:
Future<void> _scrollViewDialog(BuildContext context) async {
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return showDialog<void>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Rewind and remember'),
content: SingleChildScrollView(
child: ListBody(
// 每个字母显示的布局
children: str.split("").map((c) => Text(c,textScaleFactor: 2.0,)).toList()
),
),
backgroundColor: Colors.red[200],
elevation: 10,
semanticLabel: 'AlertDialog',
// 设置圆角
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
actions: <Widget>[
FlatButton(
child: Text('Regret'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Agree'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
免责弹窗实现
实现源码来自 GitHub Flutter-Go,这里在
Flutter-WanAndroid
中借鉴使用了,Flutter-WanAndroid 中的源码
实现解析:圆角弹窗中有标题和内容,内容长度可滑动。底部左侧的Checkbox
和右侧的按钮是联动关系,勾选Check
之后知道了
按钮才可以点击。这里选择使用AlertDialog
来实现。
- 标题和内容都放在
AlertDialog
的content
中,并使用SingleChildScrollView
来承载这个content
。 - 圆角弹窗使用
AlertDialog
的shape
中来实现,这里使用RoundedRectangleBorder
来设置圆角。 - 底部的
Checkbox
和按钮
使用AlertDialog
的actions
中来实现,这里使用Row
来承载Checkbox
和按钮
内容。
Toast
在
Flutter
中没有提供类似于Adnroid
的Toast
提示框。在pub.dev
找了一个lib
:fluttertoast
第三方库 fluttertoast
- 引入
dependencies:
fluttertoast: ^4.0.0
- 封装使用
1. 定义 ToastUtil 类
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ToastUtil {
static showBasicToast(String msg){
Fluttertoast.showToast(
msg: msg,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
/// cancel all the toasts call
static cancelAllToast(){
Fluttertoast.cancel();
}
}
2. 使用
ToastUtil.showBasicToast("忘记密码");
- 详细使用请查看官方文档:fluttertoast
Snackbar
带有可选操作的轻量级消息,在屏幕的底部短暂显示。
构造函数中的字段:
const SnackBar({
Key key,
@required this.content,// 内容
this.backgroundColor,// 背景颜色
this.elevation,// 阴影高度
this.shape,// 形状
this.behavior,// 定义行为和位置,有两个值:fixed(固定模式),floating(浮动模式)
this.action,// SnackBar 右边的Widget组件集合,如确认、取消按钮
this.duration = _snackBarDisplayDuration,// SnackBar 停留时间
this.animation,// SnackBar 显示/隐藏动画
this.onVisible,// 显示后的回调
})
基本使用
- 错误示范
如上图所示,运行之后会报错:
Scaffold.of() called with a context that does not contain a Scaffold.
意思是:在不包含Scaffold
的上下文中调用Scaffold.of()
是不被允许的。
- 修正:使用
Builder
去包裹一层。
详细使用示例伪代码:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SnackBar'),
),
body: Builder(
builder: (BuildContext context){
return Column(
children: <Widget>[
RaisedButton(
child: Text('show SnackBar'),
onPressed: () {
var snackBar = SnackBar(
content: new Text('show SnackBar '),
backgroundColor: Colors.red,
elevation: 10,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
behavior: SnackBarBehavior.fixed,
duration: Duration(milliseconds: 4000),
action: SnackBarAction(
label: '撤消',
textColor: Colors.white,
onPressed: () {
print("撤消");
// do something to undo
},),
onVisible: (){
print("onVisible");
},
);
//显示SnackBar
Scaffold.of(context).showSnackBar(snackBar);
},
),
],
);
},
)
);
}
顶部显示 SnackBar
在
https://pub.dev/packages/
搜索时发现顶部显示的 SnackBar
完~