引言
在 Flutter 开发中,弹窗(Dialog) 是非常常见的交互组件,常用于提示信息、加载状态、确认操作等场景。然而,在复杂项目中,使用原生 showDialog 会带来一些问题:
- 上下文依赖强:必须传入 BuildContext
- 层级嵌套问题:如在 BottomSheet 中调用 Dialog 可能报错
- 无法统一管理弹窗栈
- 动画和样式不统一
为了解决这些问题,社区推出了许多优秀的弹窗库,其中 SmartDialog 是一个功能强大、轻量易用、支持全局调用的弹窗解决方案。
为了解决这些问题,社区推出了许多优秀的弹窗库,其中 SmartDialog 是一个功能强大、轻量易用、支持全局调用的弹窗解决方案。
1. 环境准备
1.1 添加依赖
在 pubspec.yaml 中添加 SmartDialog 的依赖:
dependencies:
flutter:
sdk: flutter
smart_dialog: ^2.0.3 # 当前最新稳定版本,请根据实际情况更新
然后运行:
flutter pub get
2. 初始化 SmartDialog
为了支持全局弹窗,需要在 MaterialApp 中注册 SmartDialog 提供的导航器。
import 'package:flutter/material.dart';
import 'package:smart_dialog/smart_dialog.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 注册 SmartDialog
navigatorObservers: [SmartDialogNavigatorObserver()],
home: const HomePage(),
);
}
}
3. 基础使用示例
3.1 显示一个简单对话框
import 'package:smart_dialog/smart_dialog.dart';
SmartDialog.show(
widget: AlertDialog(
title: Text("提示"),
content: Text("这是一个 SmartDialog 示例"),
actions: [
TextButton(
onPressed: SmartDialog.dismiss,
child: Text("确定"),
)
],
),
);
3.2 显示加载框(Loading)
// 显示加载框
SmartDialog.showLoading();
// 模拟网络请求
await Future.delayed(Duration(seconds: 2));
// 隐藏加载框
SmartDialog.dismiss();
你也可以自定义 Loading 内容:
SmartDialog.showLoading(
widget: CircularProgressIndicator(),
backDismiss: false, // 是否允许点击返回关闭
);
3.3 显示 Toast 类型提示
SmartDialog 支持类似 Android Toast 的短暂提示:
SmartDialog.showToast(
"这是一条提示信息",
alignment: Alignment.bottomCenter,
durationTime: 2000,
style: TextStyle(color: Colors.white),
background: Colors.black.withOpacity(0.6),
);
4. 高级用法
4.1 自定义弹窗内容与动画
你可以完全自定义弹窗内容,并为其添加进入/退出动画。
SmartDialog.show(
animationType: SmartDialogAnimationType.scale, // 缩放动画
maskColor: Colors.black54,
clickMaskDismiss: true,
widget: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
width: 300,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("自定义弹窗", style: TextStyle(fontSize: 18)),
SizedBox(height: 16),
ElevatedButton(
onPressed: SmartDialog.dismiss,
child: Text("关闭"),
),
],
),
),
);
支持的动画类型:
- scale 缩放进入
- fade 渐显渐隐
- slide 从底部滑入
- none 无动画
4.2 弹窗堆叠(多个弹窗同时显示)
SmartDialog 支持弹窗堆叠,即可以连续打开多个弹窗:
SmartDialog.show(widget: FirstDialog());
SmartDialog.show(widget: SecondDialog());
可以通过以下方法控制当前弹窗:
SmartDialog.dismiss(); // 关闭最上层弹窗
SmartDialog.dismissAll(); // 关闭所有弹窗
4.3 弹窗回调处理(Future 返回值)
你可以在弹窗中传递参数并获取用户选择结果:
final result = await SmartDialog.show<bool>(
widget: AlertDialog(
title: Text("确认操作"),
content: Text("是否删除此条数据?"),
actions: [
TextButton(onPressed: () => SmartDialog.dismiss(result: false), child: Text("取消")),
TextButton(onPressed: () => SmartDialog.dismiss(result: true), child: Text("确定")),
],
),
);
if (result == true) {
print("用户点击了确定");
} else {
print("用户点击了取消");
}
4.4 自定义遮罩层行为
你可以控制遮罩层是否可点击关闭、颜色、透明度等:
SmartDialog.show(
maskColor: Colors.grey.withOpacity(0.5),
clickMaskDismiss: false, // 禁止点击遮罩关闭
widget: YourCustomDialogWidget(),
);
5. 最佳实践
5.1 封装通用弹窗服务类
建议封装一个 DialogService 来统一管理各类弹窗逻辑,提升复用性。
class DialogService {
static Future<bool?> showConfirmDialog({
required String title,
required String content,
}) async {
return await SmartDialog.show<bool>(
widget: AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(
onPressed: () => SmartDialog.dismiss(result: false),
child: Text("取消"),
),
TextButton(
onPressed: () => SmartDialog.dismiss(result: true),
child: Text("确定"),
),
],
),
);
}
static void showLoading() {
SmartDialog.showLoading(widget: CircularProgressIndicator());
}
static void hideLoading() {
SmartDialog.dismiss();
}
}
5.2 结合 GetX / Provider 使用更高效
如果你使用了 GetX 或 Provider,可以将 DialogService 作为服务注入或单例使用,进一步解耦 UI 和业务逻辑。