在实际开发中,我们会经常用到各种Dialog,这里我介绍8种常见的 Dialog 和如何自定义 Dialog。
下面介绍8种样式的Dialog
1.AlertDialog
AlertDialog是比较常用的 Dialog,这是系统提供的控件。我们可以根据传参控制显示的样式,这里我都写了一个异步获取结果的方法.
AlertDialog的属性:
- title:标题
- titlePadding:标题内边距
- titleTextStyle:标题样式
- content:内容,推荐用SingleChildScrollView包裹
- contentPadding:EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),内容内边距
- contentTextStyle:内容样式
- actions:按钮集合,可以放多个
- actionsPadding:EdgeInsets.zero,actions内边距
- buttonPadding:按钮内边距
- backgroundColor:背景色
- elevation:阴影
- shape:形状
- scrollable = false:
具体实现代码示例:
_alertDialog() async {
var result = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('这是一个Dialog'),
content: Text('这是一个alertDialog类型的Dialog'),
actions: <Widget>[
TextButton(
child: Text(
'取消',
style: TextStyle(color: Colors.grey),
),
onPressed: () {
Navigator.pop(context, "取消");
}),
TextButton(
child: Text(
'确定',
style: TextStyle(color: Colors.blue),
),
onPressed: () {
Navigator.pop(context, "确定");
},
),
],
);
});
print(result);
}
2. SimpleDialog
SimpleDialog这个是在屏幕中间显示,可选项的一个弹窗,这在实际中也经常用到
SimpleDialog属性:
- title:标题
- titlePadding:EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),标题内边距
- titleTextStyle:标题样式
- children:子节点
- contentPadding:EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),内容内边距
- backgroundColor:背景色
- elevation:阴影
- shape:形状
SimpleDialog的实现代码示例:
_simpleDialog() async {
var result = await showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: Text('选择对应内容'),
children: <Widget>[
SimpleDialogOption(
child: Text('这是第一个选项'),
onPressed: () {
Navigator.pop(context, 'A');
},
),
Divider(),
SimpleDialogOption(
child: Text('这是第二个选项'),
onPressed: () {
Navigator.pop(context, 'B');
},
),
Divider(),
SimpleDialogOption(
child: Text('这是第三个选项'),
onPressed: () {
Navigator.pop(context, 'C');
},
),
],
);
});
print(result);
}
3. ShowModalBottomSheet
ModalBottomSheet底部面板,相当于弹出了一个新页面,有点类似于 ActionSheet
ModalBottomSheet的属性:
- context:BuildContext
- builder:WidgetBuilder
- backgroundColor:背景色
- elevation:阴影
- shape:形状
- barrierColor:遮盖背景颜色
- isDismissible:点击遮盖背景是否可消失
- enableDrag:下滑消失
ModalBottomSheet 的实现代码示例:
_modelBottomSheet() async {
var result = await showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: 234,
child: Column(
children: <Widget>[
ListTile(
title: Text(
'相机',
textAlign: TextAlign.center,
),
onTap: () {
Navigator.pop(context, '相机');
},
),
Divider(),
ListTile(
title: Text(
'图片',
textAlign: TextAlign.center,
),
onTap: () {
Navigator.pop(context, '图片');
},
),
Container(
height: 10,
color: Color(0xFFf2f2f2),
),
ListTile(
title: Text('取消', textAlign: TextAlign.center),
onTap: () {
Navigator.pop(context, '取消');
},
),
],
),
);
},
);
print(result);
}
4. CupertinoAlertDialog
这个是苹果样式的 AlertDialog,第一个是 Android 样式的
CupertinoAlertDialog的属性:
- title:标题
- content:内容
- actions = const []:actions
- scrollController:控制器
- actionScrollController:action控制器
- insetAnimationDuration = const Duration(milliseconds: 100):动画时长
- insetAnimationCurve = Curves.decelerate:动画显示的曲线
注意点:
- 需要使用 showCupertinoDialog,当然用 showDialog 也是可以的,区别就是 showCupertinoDialog 点击弹框外是不能取消弹框的,showDialog是可以的,然后就是背景透明度也是不一样的
- 如果加入了国际化的话或报错'The getter alertDialogLabel was called on null',需要配置FallbackCupertinoLocalisationsDelegate
- CupertinoAlertDialog 内部嵌套的是 SingleChildScrollView,内容超长是不会有问题的,不需要重复嵌套
- Material 跟 Cupertino 组件也是可以混用的
CupertinoAlertDialog的实现代码示例:
void showCupertinoDialogStyle() async {
var result = await showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('这是标题'),
content: Text(
"这样的样式就和苹果原生一样",
),
actions: <Widget>[
CupertinoButton(
child: Text("取消"),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text("确定"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
});
print(result);
}
5. CupertinoActionSheet
苹果式样的底部弹出选择框。
CupertinoActionSheet 的属性:
actions的子组件一般使用CupertinoActionSheetAction组件,CupertinoActionSheetAction 组件向按钮组件一样,提供了子控件和onPressed回调,isDefaultAction属性设置为true时,文字加粗,isDestructiveAction属性设置为true时,文字颜色变为红色
CupertinoActionSheet的实现代码示例:
void showCupertinoActionSheet() async {
var result = await showCupertinoModalPopup(
context: context,
builder: (context) {
return CupertinoActionSheet(
title: Text('温馨提示'),
message: Text('是否要删除?'),
actions: [
CupertinoActionSheetAction(
child: Text('删除'),
onPressed: () {},
isDefaultAction: true,
),
CupertinoActionSheetAction(
child: Text('暂时不删'),
onPressed: () {},
isDestructiveAction: true,
),
],
cancelButton: CupertinoActionSheetAction(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop('cancel');
},
),
);
});
print('${result}');
}
6. 确认弹窗
AlertDialog的实现代码示例:
void showCupertinoDialogSure() {
var dialog = CupertinoAlertDialog(
title: Text('标题标题'),
content: Text(
"这是一个描述文本",
style: TextStyle(fontSize: 20),
),
actions: <Widget>[
CupertinoButton(
child: Text("确定"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
showDialog(context: context, builder: (_) => dialog);
}
7. 自定义弹窗
这样包含两个,升级弹窗和Alert弹窗。
实现代码示例:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
//定义枚举类型
enum DialogType { upgrade, alert }
class CustomDialog extends Dialog {
final String? title; //标题
final String? content; //内容
final DialogType? dialogType;
final void Function()? cancelCallBack;
final void Function()? confirmCallBack;
CustomDialog(
{this.title,
this.content,
this.dialogType,
this.confirmCallBack,
this.cancelCallBack});
@override
Widget build(BuildContext context) {
switch (this.dialogType) {
case DialogType.upgrade:
return Material(
type: MaterialType.transparency,
child: Center(
child: upgradeDialog(context),
),
);
break;
case DialogType.alert:
return Material(
type: MaterialType.transparency,
child: Center(
child: customAlertDialog(context),
),
);
break;
default:
return Material(
type: MaterialType.transparency,
child: Center(
child: upgradeDialog(context),
),
);
}
}
//自定义Alert弹窗
Widget customAlertDialog(BuildContext context) {
return Container(
height: 300,
margin: EdgeInsets.only(left: 40, right: 40),
color: Colors.white,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(20),
child: Stack(
children: [
Align(
child: Text(
title!,
style: TextStyle(fontSize: 20, color: Color(0xFF2D2D2D)),
),
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
child: Icon(Icons.close),
onTap: () {
Navigator.of(context).pop();
},
),
),
],
),
),
Divider(),
Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
content!,
textAlign: TextAlign.left,
),
)
],
),
);
}
//自定义升级弹窗
Widget upgradeDialog(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.only(left: 20, right: 20),
decoration: const ShapeDecoration(
color: Color(0xfff2f2f2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
),
child: Column(
children: [
Container(
height: 250,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
image: DecorationImage(
image: AssetImage('images/head_icon.png'),
fit: BoxFit.cover,
)),
),
SizedBox(
height: 20,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
width: double.infinity,
child: const Text(
'本次更新',
style: TextStyle(
fontSize: 20,
color: Color(0xFF2D2D2D),
decoration: TextDecoration.none),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 15,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
width: double.infinity,
child: Text(
'解决了一些已知问题',
style: TextStyle(
fontSize: 16,
color: Color(0xFF333333),
decoration: TextDecoration.none),
textAlign: TextAlign.left,
),
),
SizedBox(
height: 20,
),
Divider(),
Container(
height: 40,
margin: EdgeInsets.only(bottom: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
this.confirmCallBack!();
},
child: Text(
'升级',
style: TextStyle(fontSize: 18),
),
),
VerticalDivider(
color: Colors.grey,
width: 1,
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
this.cancelCallBack!();
},
child: Text('暂不升级', style: TextStyle(fontSize: 18))),
],
),
)
],
),
)
],
),
);
}
}
8. Toast提示框
这里我用到了一个包fluttertoast,需要先在./pubspec.yaml中引入包
fluttertoast: ^8.0.8
然后在终端运行
flutter pub get
接着就在项目中导入
import 'package:fluttertoast/fluttertoast.dart';
fluttertoast 属性参数:
msg:toast展示的信息
gravity:toast展示的位置
timeInSecForIosWeb:显示的秒数,到时间自动消失
backgroundColor:背景色
textColor:文字颜色
fontSize:字体大小
实现的示例代码
showToast() {
Fluttertoast.showToast(
msg: '取消点击',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black45,
textColor: Colors.white,
fontSize: 16.0,
);
}
以上就是写的常用的Dialog。其实在实际开发中可以参考系统的组件,我们可以根据自己的需求来自定义,控制传入的title、message、文字颜色、字体、大小、事件的回调等等。