Flutter 对话框与提示组件学习
Flutter 提供了多种对话框和提示组件,用于与用户进行交互、显示信息或获取输入。下面我将详细介绍常用的对话框和提示组件。
1. 基础对话框组件
1.1 AlertDialog - 警告对话框
dart
import 'package:flutter/material.dart';
class DialogExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('对话框示例')),
body: Center(
child: ElevatedButton(
child: Text('显示警告对话框'),
onPressed: () => _showAlertDialog(context),
),
),
);
}
void _showAlertDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false, // 点击遮罩层是否关闭对话框
builder: (BuildContext context) {
return AlertDialog(
title: Text('提示'),
content: Text('确定要删除这条记录吗?'),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
print('用户点击了取消');
},
),
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop();
print('用户点击了确定');
},
),
],
);
},
);
}
}
1.2 SimpleDialog - 简单选择对话框
dart
void _showSimpleDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: Text('选择颜色'),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '红色');
},
child: Text('红色'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '绿色');
},
child: Text('绿色'),
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, '蓝色');
},
child: Text('蓝色'),
),
],
);
},
).then((value) {
if (value != null) {
print('用户选择了: $value');
}
});
}
1.3 Dialog - 自定义对话框
dart
void _showCustomDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Container(
padding: EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.check_circle,
color: Colors.green,
size: 60,
),
SizedBox(height: 20),
Text(
'操作成功',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
Text('您的操作已成功完成'),
SizedBox(height: 20),
ElevatedButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
),
);
},
);
}
2. 输入对话框
2.1 文本输入对话框
dart
void _showTextInputDialog(BuildContext context) {
final TextEditingController _controller = TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('请输入'),
content: TextField(
controller: _controller,
decoration: InputDecoration(
hintText: '请输入内容',
border: OutlineInputBorder(),
),
),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('确定'),
onPressed: () {
String inputText = _controller.text;
Navigator.of(context).pop(inputText);
},
),
],
);
},
).then((value) {
if (value != null) {
print('用户输入了: $value');
}
});
}
2.2 多字段输入对话框
dart
void _showMultiFieldDialog(BuildContext context) {
final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('用户信息'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _nameController,
decoration: InputDecoration(
labelText: '姓名',
border: OutlineInputBorder(),
),
),
SizedBox(height: 10),
TextField(
controller: _emailController,
decoration: InputDecoration(
labelText: '邮箱',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
),
],
),
),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () => Navigator.of(context).pop(),
),
TextButton(
child: Text('提交'),
onPressed: () {
final userInfo = {
'name': _nameController.text,
'email': _emailController.text,
};
Navigator.of(context).pop(userInfo);
},
),
],
);
},
).then((value) {
if (value != null) {
print('用户信息: $value');
}
});
}
3. 底部弹出对话框
3.1 模态底部对话框
dart
void _showModalBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children: [
ListTile(
leading: Icon(Icons.share),
title: Text('分享'),
onTap: () {
Navigator.pop(context);
print('点击了分享');
},
),
ListTile(
leading: Icon(Icons.copy),
title: Text('复制'),
onTap: () {
Navigator.pop(context);
print('点击了复制');
},
),
ListTile(
leading: Icon(Icons.delete),
title: Text('删除'),
onTap: () {
Navigator.pop(context);
print('点击了删除');
},
),
],
),
);
},
);
}
3.2 带滚动效果的底部对话框
dart
void _showScrollableBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true, // 允许滚动
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.5, // 初始高度为屏幕的50%
maxChildSize: 0.9, // 最大高度为屏幕的90%
minChildSize: 0.3, // 最小高度为屏幕的30%
expand: false,
builder: (context, scrollController) {
return ListView.builder(
controller: scrollController,
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('选项 ${index + 1}'),
onTap: () {
Navigator.pop(context);
print('选择了选项 ${index + 1}');
},
);
},
);
},
),
);
}
4. 提示组件
4.1 SnackBar - 底部提示条
dart
void _showSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('这是一条提示信息'),
duration: Duration(seconds: 2),
action: SnackBarAction(
label: '撤销',
onPressed: () {
print('点击了撤销');
},
),
behavior: SnackBarBehavior.floating, // 浮动显示
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
}
4.2 自定义 SnackBar
dart
void _showCustomSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(Icons.check_circle, color: Colors.white),
SizedBox(width: 10),
Expanded(
child: Text(
'操作成功!',
style: TextStyle(fontSize: 16),
),
),
],
),
backgroundColor: Colors.green,
duration: Duration(seconds: 3),
),
);
}
5. 进度对话框
5.1 简单的加载对话框
dart
void _showLoadingDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false, // 不可点击遮罩层关闭
builder: (BuildContext context) {
return Dialog(
child: Padding(
padding: EdgeInsets.all(20),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(width: 20),
Text("加载中..."),
],
),
),
);
},
);
// 模拟3秒后关闭
Future.delayed(Duration(seconds: 3), () {
Navigator.of(context).pop(); // 关闭对话框
});
}
5.2 带进度条的对话框
dart
void _showProgressDialog(BuildContext context) {
double progressValue = 0.0;
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
// 模拟进度更新
Future.delayed(Duration(milliseconds: 100), () {
if (progressValue < 1.0) {
setState(() {
progressValue += 0.1;
});
}
});
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
LinearProgressIndicator(
value: progressValue,
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
SizedBox(height: 10),
Text('${(progressValue * 100).toInt()}%'),
],
),
);
},
);
},
);
}
6. 综合示例:完整对话框应用
dart
import 'package:flutter/material.dart';
class DialogDemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '对话框示例',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: DialogDemoHome(),
);
}
}
class DialogDemoHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('对话框与提示示例'),
),
body: ListView(
padding: EdgeInsets.all(16),
children: [
_buildDialogButton(
context,
'警告对话框',
'显示一个带确认和取消按钮的警告对话框',
_showAlertDialog,
),
_buildDialogButton(
context,
'选择对话框',
'显示一个简单的选择对话框',
_showSimpleDialog,
),
_buildDialogButton(
context,
'输入对话框',
'显示一个文本输入对话框',
_showTextInputDialog,
),
_buildDialogButton(
context,
'底部对话框',
'从底部弹出的对话框',
_showModalBottomSheet,
),
_buildDialogButton(
context,
'SnackBar提示',
'显示底部提示条',
_showCustomSnackBar,
),
_buildDialogButton(
context,
'加载对话框',
'显示加载中的对话框',
_showLoadingDialog,
),
],
),
);
}
Widget _buildDialogButton(
BuildContext context,
String title,
String subtitle,
VoidCallback onPressed,
) {
return Card(
margin: EdgeInsets.only(bottom: 12),
child: ListTile(
title: Text(title),
subtitle: Text(subtitle),
trailing: Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => onPressed(),
),
);
}
// 各对话框方法...(同上)
}
7. 最佳实践与注意事项
7.1 对话框状态管理
- 使用
StatefulBuilder在对话框内部更新状态 - 避免在对话框关闭后引用已销毁的上下文
7.2 响应式设计
- 考虑不同屏幕尺寸下对话框的显示效果
- 在大屏幕上使用不同大小的对话框
7.3 用户体验
- 提供明确的关闭按钮或操作
- 在长时间操作时显示进度指示器
- 避免过度使用模态对话框,影响用户操作流程
7.4 代码组织
- 将复杂的对话框逻辑封装为独立组件
- 使用常量定义对话框的文本内容
- 保持对话框的简洁和专注
8. 第三方库推荐
8.1 fluttertoast - Toast提示
yaml
dependencies:
fluttertoast: ^8.2.4
使用示例:
dart
import 'package:fluttertoast/fluttertoast.dart';
Fluttertoast.showToast(
msg: "这是一个Toast提示",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.grey[800],
textColor: Colors.white,
fontSize: 16.0
);
8.2 rflutter_alert - 增强对话框
yaml
dependencies:
rflutter_alert: ^2.0.4
总结
Flutter 提供了丰富的对话框和提示组件,可以满足大多数应用场景的需求。通过灵活使用这些组件,可以创建出既美观又实用的用户交互界面。记住关键点:
- 选择合适的对话框类型
- 保持对话框内容简洁明了
- 提供明确的用户操作路径
- 考虑不同平台的设计规范
- 测试在各种设备和屏幕尺寸下的显示效果