对话框组件详解
对话框是与用户交互的重要方式,用于显示重要信息、确认操作或收集输入。Flutter 提供了多种对话框组件。本教程将详细介绍各种对话框。
重要提示:Flutter 3.28+ 增强了对话框的样式和动画效果,提供更好的用户体验。
1. AlertDialog 警告对话框
AlertDialog 是最常用的对话框,用于显示警告、确认信息。
📐 AlertDialog 渲染效果
// 基本对话框
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('确认删除'),
content: const Text('确定要删除这个项目吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
TextButton(
onPressed: () {
Navigator.pop(context);
// 执行删除操作
},
child: const Text('删除'),
),
],
),
);
// 带图标的对话框
showDialog(
context: context,
builder: (context) => AlertDialog(
icon: const Icon(Icons.warning, color: Colors.orange),
title: const Text('警告'),
content: const Text('此操作不可撤销!'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('知道了'),
),
],
),
);
2. SimpleDialog 简单对话框
SimpleDialog 用于提供选项列表供用户选择。
📐 SimpleDialog 渲染效果
showDialog(
context: context,
builder: (context) => SimpleDialog(
title: const Text('选择操作'),
children: [
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '查看');
},
child: const Text('查看详情'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '编辑');
},
child: const Text('编辑'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '删除');
},
child: const Text('删除'),
),
],
),
).then((value) {
if (value != null) {
print('选择了: $value');
}
});
3. BottomSheet 底部表单
BottomSheet 从屏幕底部滑出,适合显示更多内容。
📐 BottomSheet 渲染效果
// 模态底部表单
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => Container(
padding: const EdgeInsets.all(20),
height: 300,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'选择日期',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 20),
const TextField(
decoration: InputDecoration(
labelText: '日期',
hintText: '请选择日期',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
),
);
// 持久底部表单
Scaffold(
body: const Center(child: Text('内容')),
bottomSheet: Container(
height: 100,
color: Colors.blue,
child: const Center(
child: Text('底部表单', style: TextStyle(color: Colors.white)),
),
),
);
4. SnackBar 轻量提示
SnackBar 用于显示简短的消息提示。
📐 SnackBar 渲染效果
从底部弹出,短暂显示后自动消失
// 基本提示
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('操作成功')),
);
// 带动作的提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('已删除'),
action: SnackBarAction(
label: '撤销',
onPressed: () {
// 撤销操作
},
),
),
);
// 带图标的提示
final snackBar = SnackBar(
content: const Row(
children: [
Icon(Icons.check_circle, color: Colors.white),
SizedBox(width: 8),
Text('保存成功'),
],
),
backgroundColor: Colors.green,
duration: const Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
5. showDialog 显示对话框
showDialog 是显示对话框的核心方法。
📐 showDialog 返回值流程
1. 显示对话框
页面内容
确认
确定要继续吗?
→
2. 用户选择
取消
确定
→
3. 返回结果
true/false
showDialog 返回 Future,可以获取用户选择的值
// 带返回值的对话框
Future showConfirmDialog(BuildContext context) {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('确认'),
content: const Text('确定要继续吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('确定'),
),
],
),
);
}
// 使用
final confirmed = await showConfirmDialog(context);
if (confirmed == true) {
print('用户确认了');
}
6. showDialog 全局对话框
使用 navigatorKey 显示全局对话框。
📐 全局对话框工作原理
MaterialApp
App
navigatorKey
↓
任意位置调用
showDialog()
↓
显示对话框
全局对话框
无需 context
通过 GlobalKey 在应用任何位置显示对话框,不受页面层级限制
// 在 MaterialApp 中设置 navigatorKey
final GlobalKey navigatorKey = GlobalKey();
MaterialApp(
navigatorKey: navigatorKey,
home: const HomePage(),
);
// 在任何地方显示对话框
void showGlobalDialog() {
showDialog(
context: navigatorKey.currentContext!,
builder: (context) => AlertDialog(
title: const Text('全局对话框'),
content: const Text('这是一个全局对话框'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
],
),
);
}
7. DatePickerDialog 日期选择器
日期选择器用于选择日期。
📐 DatePickerDialog 渲染效果
日历视图,支持选择年月日
// 显示日期选择器
Future _selectDate() async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030),
helpText: '选择日期',
cancelText: '取消',
confirmText: '确定',
locale: const Locale('zh', 'CN'),
);
if (picked != null) {
setState(() {
_selectedDate = picked;
});
}
}
// 显示日期范围选择器
Future _selectDateRange() async {
final DateTimeRange? picked = await showDateRangePicker(
context: context,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
helpText: '选择日期范围',
cancelText: '取消',
confirmText: '确定',
saveText: '保存',
);
if (picked != null) {
setState(() {
_dateRange = picked;
});
}
}
8. TimePickerDialog 时间选择器
时间选择器用于选择时间。
📐 TimePickerDialog 渲染效果
24小时制,分别选择小时和分钟
// 显示时间选择器
Future _selectTime() async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
helpText: '选择时间',
cancelText: '取消',
confirmText: '确定',
);
if (picked != null) {
setState(() {
_selectedTime = picked;
});
}
}
9. showDialog 自定义对话框
创建自定义样式的对话框。
📐 自定义对话框效果
使用 Dialog 组件实现完全自定义的样式
showDialog(
context: context,
builder: (context) => Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 10,
spreadRadius: 5,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.check_circle,
color: Colors.green,
size: 60,
),
const SizedBox(height: 20),
const Text(
'操作成功',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
const Text(
'您的操作已成功完成',
style: TextStyle(color: Colors.grey),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
minimumSize: const Size(double.infinity, 48),
),
child: const Text('确定'),
),
],
),
),
),
);
🔀 对话框选择流程图
需要提示用户
↓
信息类型?
轻量提示
↓
SnackBar
简单确认
↓
AlertDialog
底部操作
↓
BottomSheet
↓
完成选择
📊 对话框组件对比
| 组件 | 位置 | 内容 | 使用场景 |
|---|---|---|---|
| AlertDialog | 屏幕中央 | 简单 | 确认对话框 |
| BottomSheet | 底部 | 丰富 | 底部菜单/表单 |
| SnackBar | 底部 | 轻量 | 提示消息 |
| SimpleDialog | 屏幕中央 | 选项 | 选项选择 |
| ModalBarrier | 全屏 | 遮罩 | 背景遮罩 |
对话框最佳实践
- 对话框应该简洁明了,不要包含过多信息
- 为对话框提供清晰的标题和操作按钮
- 使用 SnackBar 显示轻量级提示
- BottomSheet 适合显示大量内容或复杂表单
- 为对话框提供合适的动画效果
- 确保对话框在不同设备上都能正常显示
- 使用 Material Design 3 的对话框样式
- 为危险操作提供明确的警告
提示:使用 showAboutDialog 可以显示应用信息。
下一步:掌握对话框组件后,继续学习动画组件。