Flutter 弹窗封装:支持多种常见弹框,灵活易用
在 Flutter 开发中,弹窗(Dialog)是常见的 UI 组件,用于提示信息、确认操作、输入内容等。为了提高代码复用性和开发效率,我们可以将弹窗封装成一个通用的工具类,支持多种常见弹框类型,包括:
- 通用弹窗:显示标题、内容和操作按钮。
- 确认弹框:用于确认用户操作(如删除、退出等)。
- 输入弹框:允许用户输入文本。
- 选择弹框:提供多个选项供用户选择。
- 加载弹框:显示加载状态。
- 底部弹框:从屏幕底部弹出的弹框。
通过封装,弹窗的调用更加简洁,代码更易维护,同时支持高度自定义样式和异步操作。
封装代码
import 'package:flutter/material.dart';
class DialogHelper {
// 显示通用弹窗
static Future<void> showCustomDialog({
required BuildContext context,
String? title,
String? content,
List<Widget>? actions,
Widget? customContent,
Color? backgroundColor,
TextStyle? titleStyle,
TextStyle? contentStyle,
}) async {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: backgroundColor,
title: title != null
? Text(
title!,
style: titleStyle ?? Theme.of(context).textTheme.headline6,
)
: null,
content: customContent ??
(content != null
? Text(
content!,
style: contentStyle ?? Theme.of(context).textTheme.bodyText2,
)
: null),
actions: actions,
);
},
);
}
// 显示确认弹框
static Future<bool?> showConfirmDialog({
required BuildContext context,
String? title,
String? content,
String confirmText = '确认',
String cancelText = '取消',
}) async {
return showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
title: title != null ? Text(title) : null,
content: content != null ? Text(content) : null,
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(cancelText),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text(confirmText),
),
],
);
},
);
}
// 显示输入弹框
static Future<String?> showInputDialog({
required BuildContext context,
String? title,
String? hintText,
String confirmText = '确认',
String cancelText = '取消',
}) async {
final TextEditingController controller = TextEditingController();
return showDialog<String>(
context: context,
builder: (context) {
return AlertDialog(
title: title != null ? Text(title) : null,
content: TextField(
controller: controller,
decoration: InputDecoration(hintText: hintText),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(cancelText),
),
TextButton(
onPressed: () => Navigator.of(context).pop(controller.text),
child: Text(confirmText),
),
],
);
},
);
}
// 显示选择弹框
static Future<void> showSelectionDialog({
required BuildContext context,
String? title,
required List<String> options,
}) async {
return showDialog(
context: context,
builder: (context) {
return SimpleDialog(
title: title != null ? Text(title) : null,
children: options.map((option) {
return SimpleDialogOption(
onPressed: () {
Navigator.of(context).pop(option);
},
child: Text(option),
);
}).toList(),
);
},
);
}
// 显示加载弹框
static Future<void> showLoadingDialog({
required BuildContext context,
String? message,
}) async {
return showDialog(
context: context,
barrierDismissible: false, // 点击外部不可关闭
builder: (context) {
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text(message ?? '加载中...'),
],
),
);
},
);
}
// 显示底部弹框
static Future<void> showBottomSheetDialog({
required BuildContext context,
required Widget child,
}) async {
return showModalBottomSheet(
context: context,
builder: (context) {
return child;
},
);
}
}
使用示例
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter 弹窗封装示例'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
DialogHelper.showCustomDialog(
context: context,
title: '提示',
content: '这是一个通用弹窗示例。',
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('关闭'),
),
],
);
},
child: Text('显示通用弹窗'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
bool? result = await DialogHelper.showConfirmDialog(
context: context,
title: '确认删除',
content: '确定要删除此项吗?',
);
if (result == true) {
print('用户确认删除');
} else {
print('用户取消删除');
}
},
child: Text('显示确认弹框'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
String? result = await DialogHelper.showInputDialog(
context: context,
title: '输入内容',
hintText: '请输入文本',
);
if (result != null) {
print('用户输入: $result');
}
},
child: Text('显示输入弹框'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
String? result = await DialogHelper.showSelectionDialog(
context: context,
title: '选择一个选项',
options: ['选项1', '选项2', '选项3'],
);
if (result != null) {
print('用户选择: $result');
}
},
child: Text('显示选择弹框'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
DialogHelper.showLoadingDialog(
context: context,
message: '请稍候...',
);
// 模拟异步操作
Future.delayed(Duration(seconds: 2), () {
Navigator.of(context).pop(); // 关闭弹窗
});
},
child: Text('显示加载弹框'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
DialogHelper.showBottomSheetDialog(
context: context,
child: Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('这是一个底部弹框'),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('关闭'),
),
],
),
),
);
},
child: Text('显示底部弹框'),
),
],
),
),
),
);
}
}
优点
- 支持多种弹框类型:覆盖常见的使用场景。
- 调用简洁:通过静态方法调用,代码更清晰。
- 高度可定制:支持自定义样式、内容和操作。
- 异步支持:通过
Future
处理用户操作结果。 - 易于扩展:可以根据需求继续扩展其他弹框类型。
通过这种封装方式,Flutter 弹窗的使用变得更加灵活和高效!