1. 基本介绍
SimpleDialog、AlertDialog、CupertinoAlertDialog、Dialog 都是最常见的弹框提示。
CupertinoAlertDialog 是 iOS 风格弹框。
showDialog、showCupertinoDialog 是两个调用弹框的 api,基本没啥区别,使用也没有什么限制。
2. 示例代码
代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。
3. 属性介绍
3.1 SimpleDialog 属性介绍
SimpleDialog属性 | 介绍 |
---|---|
title | 标题 |
titlePadding | 标题外间距,默认为 const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0), |
titleTextStyle | 标题样式 TextStyle |
children | 子控件,可以随意自定义 |
contentPadding | 内容外间距,默认为 const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0) |
backgroundColor | 背景色 |
elevation | 阴影高度 |
semanticLabel | 语义标签 |
shape | 形状 ShapeBorder |
3.2 AlertDialog 属性介绍
AlertDialog属性 | 介绍 |
---|---|
title | 标题 |
titlePadding | 标题外间距,默认为 const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0), |
titleTextStyle | 标题样式 TextStyle |
content | 内容控件 |
contentPadding | 内容外间距,默认为 const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0) |
contentTextStyle | 内容文本样式 TextStyle |
actions | 事件子控件组 |
actionsPadding | 事件子控件间距,默认为 EdgeInsets.zero, |
actionsOverflowDirection | 事件过多时,竖向展示顺序,只有正向和反向,默认为 VerticalDirection.down |
actionsOverflowButtonSpacing | 事件过多时,竖向展示时,子控件间距 |
buttonPadding | actions 中每个按钮边缘填充距离,默认为左右各 8.0 |
backgroundColor | 背景色 |
elevation | 阴影高度 |
semanticLabel | 语义标签 |
insetPadding | 对话框距离屏幕边缘间距,默认为 EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0) |
clipBehavior | 超出部分剪切方式,Clip.none |
shape | 形状 ShapeBorder |
scrollable | 是否可以滚动,默认为 false |
3.3 CupertinoAlertDialog 属性介绍
CupertinoAlertDialog属性 | 介绍 |
---|---|
title | 标题 |
content | 内容控件 |
actions | 事件子控件组 |
scrollController | 滚动控制器,内容超出高度,content 可以滑动 |
actionScrollController | actions 滚动控制器,actions超出高度,actions 可以滑动 |
insetAnimationDuration | 动画时间,默认为 const Duration(milliseconds: 100) |
insetAnimationCurve | 动画效果,渐进渐出等等,默认为 Curves.decelerate |
3.4 Dialog 属性介绍
Dialog属性 | 介绍 |
---|---|
backgroundColor | 背景色 |
elevation | 阴影高度 |
insetAnimationDuration | 动画时间,默认为 const Duration(milliseconds: 100) |
insetAnimationCurve | 动画效果,渐进渐出等等,默认为 Curves.decelerate |
insetPadding | 对话框距离屏幕边缘间距,默认为 EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0) |
clipBehavior | 超出部分剪切方式,Clip.none |
shape | 形状 ShapeBorder |
child | 自定义弹框 |
4. Dialog调用方法详解
4.1 showDialog 详解
showDialog 是控制 Dialog 弹出的 api。下文有具体使用,这里就简单介绍一下常用属性。
showDialog常用属性 | 介绍 |
---|---|
context | 上下文 |
builder | (context){ return widget;} 返回一个 Widget 作为弹框展示内容 |
barrierDismissible | 点击背后蒙层是否关闭弹框,默认为 true |
barrierColor | 背后蒙层颜色 |
useSafeArea | 是否使用安全区域,默认为 true |
useRootNavigator | 是否使用根导航,默认为 true |
routeSettings | 路由设置 |
child | 子控件,和使用 builder 返回一个 widget 同样效果 |
4.2 showCupertinoDialog 详解
showCupertinoDialog 也是控制 Dialog 弹出的 api。其实与 showDialog 一样,两者都可以调用各种弹框,但是 showCupertinoDialog 默认是不可以点击空白区域隐藏的。
showCupertinoDialog常用属性 | 介绍 |
---|---|
context | 上下文 |
builder | (context){ return widget;} 返回一个 Widget 作为弹框展示内容 |
useRootNavigator | 是否使用根导航,默认为 true |
barrierDismissible | 点击背后蒙层是否关闭弹框,默认为 false |
routeSettings | 路由设置 |
5. SimpleDialog 详解
SimpleDialog 的属性都比较简单,下方写两个不同的 Dialog,备注基本写的很明白了,就不赘述了,不明白的属性可以参考最上方表格。
import 'package:flutter/material.dart';
class FMDialogVC extends StatefulWidget {
@override
FMDialogState createState() => FMDialogState();
}
class FMDialogState extends State {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
],
),
);
}
RaisedButton _showDialog(context, title, dialog){
return RaisedButton(
child: Text("$title"),
// 设置异步回调
onPressed: () async {
// 接收点击自己反参的值
var result = await showDialog(
context: context,
barrierColor: Colors.red.withAlpha(30),
barrierDismissible: true,
// builder: (context){
// return dialog;
// },
child: dialog,
);
print(result);
},
);
}
SimpleDialog _simpleDialogForNormal(context){
return SimpleDialog(
title: Text("SimpleDialog - Normal"), // 标题
titlePadding: EdgeInsets.fromLTRB(20, 20, 0, 0), // 标题外间距
// 标题样式 TextStyle
titleTextStyle: TextStyle(
color: Colors.blue,
fontSize: 25,
),
contentPadding: EdgeInsets.only(left: 15, right: 15), // 内容外间距
backgroundColor: Colors.white, // 背景色
// 子控件,可以随意自定义
children: [
Container(
child: Text("这就是最简单的 Dialog 了, 也可以在这里自定义样式。"),
alignment: Alignment.center,
padding: EdgeInsets.all(40),
),
FlatButton(
onPressed: (){
// 隐藏弹框
Navigator.pop(context, 'SimpleDialog - Normal, 我知道了');
},
child: Text("我知道了"),
textColor: Colors.white,
color: Colors.blue,
),
],
);
}
}
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
],
),
);
}
SimpleDialog _simpleDialogForShape(context){
return SimpleDialog(
title: Text("SimpleDialog - Shape"), // 标题
titlePadding: EdgeInsets.fromLTRB(20, 20, 0, 0), // 标题外间距
// 标题样式 TextStyle
titleTextStyle: TextStyle(
color: Colors.blue,
fontSize: 25,
),
contentPadding: EdgeInsets.only(left: 15, right: 15), // 内容外间距
backgroundColor: Colors.yellow, // 背景色
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
side: BorderSide(
color: Colors.red,
width: 1,
),
),
// 子控件,可以随意自定义
children: [
Container(
child: Text("这就是最简单的 Dialog 了, 也可以在这里自定义样式。"),
alignment: Alignment.center,
padding: EdgeInsets.all(40),
),
FlatButton(
onPressed: (){
// 隐藏弹框
Navigator.pop(context, 'SimpleDialog - Shape, 我知道了');
},
child: Text("我知道了"),
textColor: Colors.white,
color: Colors.blue,
),
],
);
}
6. AlertDialog 详解
AlertDialog 的属性都比较简单,下方写两个不同的 Dialog,备注基本写的很明白了,就不赘述了,不明白的属性可以参考最上方表格。
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
// _showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
],
),
);
}
AlertDialog _alertDialogForNormal(context){
return AlertDialog(
title: Text("AlertDialog - Normal"), // 标题
titlePadding: EdgeInsets.fromLTRB(20, 20, 0, 0), // 标题外间距
// 标题样式 TextStyle
titleTextStyle: TextStyle(
color: Colors.blue,
fontSize: 25,
),
contentPadding: EdgeInsets.only(left: 15, right: 15), // 内容外间距
// 内容样式 TextStyle
contentTextStyle: TextStyle(
color: Colors.grey,
fontSize: 16,
),
// 内容控件
content: Container(
height: 100,
child: Column(
children: [
Padding(padding: EdgeInsets.all(15),),
Text("这是最简单的 AlertDialog,也可以自定义样式"),
],
),
),
backgroundColor: Colors.white, // 背景色
actionsPadding: EdgeInsets.all(15), // 事件子控件间距
// 事件子控件
actions: [
Text("也可以不放按钮的"),
FlatButton(
onPressed: (){
Navigator.pop(context, 'AlertDialog - Normal, cancel');
},
child: Text("cancel")
),
FlatButton(
onPressed: (){
Navigator.pop(context, 'AlertDialog - Normal, ok');
},
child: Text("ok"),
),
],
);
}
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
_showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
],
),
);
}
AlertDialog _alertDialogForShape(context){
return AlertDialog(
title: Text("AlertDialog - Shape"), // 标题
titlePadding: EdgeInsets.fromLTRB(20, 20, 0, 0), // 标题外间距
// 标题样式 TextStyle
titleTextStyle: TextStyle(
color: Colors.blue,
fontSize: 25,
),
contentPadding: EdgeInsets.only(left: 15, right: 15), // 内容外间距
// 内容样式 TextStyle
contentTextStyle: TextStyle(
color: Colors.grey,
fontSize: 16,
),
// 内容控件
content: Container(
height: 100,
child: Column(
children: [
Padding(padding: EdgeInsets.all(15),),
Text("这是最简单的 AlertDialog,也可以自定义样式"),
],
),
),
backgroundColor: Colors.white, // 背景色
actionsPadding: EdgeInsets.all(15), // 事件子控件间距
// 事件子控件
actions: [
Text("也可以不放按钮的"),
FlatButton(
onPressed: (){
Navigator.pop(context, 'AlertDialog - Shape, cancel');
},
child: Text("cancel")
),
FlatButton(
onPressed: (){
Navigator.pop(context, 'AlertDialog - Shape, ok');
},
child: Text("ok"),
),
],
// shape 形状
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
side: BorderSide(
color: Colors.red,
width: 1,
),
),
);
}
7. CupertinoAlertDialog 详解
CupertinoAlertDialog 是一个 iOS 风格的弹出框,与其他弹框使用方式大同小异,就不细讲了。
7.1 使用 showCupertinoDialog 调用 api 展示 CupertinoAlertDialog 普通样式。
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
_showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
],
),
);
}
// showCupertinoDialog 展示 Dialog,showCupertinoDialog 相比 showDialog 缺少部分属性,并且默认点击背景不隐藏
RaisedButton _showCupertinoDialog(context, title, dialog){
return RaisedButton(
child: Text("$title"),
onPressed: () async {
var result = await showCupertinoDialog(
context: context,
builder: (context){
return dialog;
},
);
},
);
}
CupertinoAlertDialog _cupertinoAlertDialog(context){
return CupertinoAlertDialog(
title: Text("CupertinoAlertDialog - Normal"),
content: Container(
height: 100,
child: Column(
children: [
Padding(padding: EdgeInsets.all(15),),
Text("这是最简单的 CupertinoAlertDialog,也可以自定义样式"),
],
),
),
actions: [
FlatButton(
onPressed: (){
Navigator.pop(context, 'CupertinoAlertDialog - Normal, cancel');
},
child: Text("cancel")
),
FlatButton(
onPressed: (){
Navigator.pop(context, 'CupertinoAlertDialog - Normal, ok');
},
child: Text("ok"),
),
],
);
}
7.2 使用 showCupertinoDialog 调用 api 展示 CupertinoAlertDialog 多个按钮样式。
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
_showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Three", _cupertinoAlertDialogForThree(context)),
],
),
);
}
CupertinoAlertDialog _cupertinoAlertDialogForThree(context){
return CupertinoAlertDialog(
title: Text("CupertinoAlertDialog - Normal"),
content: Container(
height: 100,
child: Column(
children: [
Padding(padding: EdgeInsets.all(15),),
Text("这是最简单的 CupertinoAlertDialog,也可以自定义样式"),
],
),
),
actions: [
FlatButton(
onPressed: (){
Navigator.pop(context, 'CupertinoAlertDialog - Three, cancel');
},
child: Text("cancel")
),
FlatButton(
onPressed: (){
Navigator.pop(context, 'CupertinoAlertDialog - Three, delete');
},
child: Text(
"delete",
style: TextStyle(
color: Colors.red,
),
),
),
FlatButton(
onPressed: (){
Navigator.pop(context, 'CupertinoAlertDialog - Three, ok');
},
child: Text("ok"),
),
],
);
}
7.3 使用 showDialog 调用 api 展示 CupertinoAlertDialog 多个按钮样式。
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
_showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Three", _cupertinoAlertDialogForThree(context)),
_showDialog(context, "Use showDialog 展示 CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
],
),
);
}
8. Dialog 详解
Dialog 是自由度最高的弹框,样式完全根据自己给 child 的值来展示,下边我就简单写一个自定义弹框。
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(title: Text("Dialog"),),
body: ListView(
padding: EdgeInsets.all(15),
children: [
_showDialog(context, "SimpleDialog - Normal", _simpleDialogForNormal(context)),
_showDialog(context, "SimpleDialog - Shape", _simpleDialogForShape(context)),
_showDialog(context, "AlertDialog - Normal", _alertDialogForNormal(context)),
_showDialog(context, "AlertDialog - Shape", _alertDialogForShape(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
_showCupertinoDialog(context, "CupertinoAlertDialog - Three", _cupertinoAlertDialogForThree(context)),
_showDialog(context, "Use showDialog 展示 CupertinoAlertDialog - Normal", _cupertinoAlertDialog(context)),
_showDialog(context, "Dialog - Custom", _customDialog(context)),
],
),
);
}
Dialog _customDialog(context){
return Dialog(
backgroundColor: Colors.yellow.shade100, // 背景色
elevation: 4.0, // 阴影高度
insetAnimationDuration: Duration(milliseconds: 300), // 动画时间
insetAnimationCurve: Curves.decelerate, // 动画效果
insetPadding: EdgeInsets.all(30), // 弹框距离屏幕边缘距离
clipBehavior: Clip.none, // 剪切方式
child: Container(
width: 300,
height: 300,
color: Colors.white,
alignment: Alignment.center,
child: Column(
children: [
Text("Custom Dialog", style: TextStyle(color: Colors.blue, fontSize: 25),),
Padding(padding: EdgeInsets.all(15)),
Text("这是一个最简单的自定义 Custom Dialog"),
Padding(padding: EdgeInsets.all(15),),
FlatButton(
onPressed: (){
// 隐藏弹框
Navigator.pop(context, 'SimpleDialog - Normal, 我知道了');
},
child: Text("我知道了"),
textColor: Colors.white,
color: Colors.blue,
),
],
),
),
);
}
9. 技术小结
Dialog 是使用非常广泛的弹框,这里需要多加练习,其实更多的样式以及布局考验的仅仅是其他组件组合的基本功。