Flutter对话框插件dh_dialog的使用
Flutter对话框插件dh_dialog的使用
dh_dialog 插件支持多种类型的对话框,包括 AlertDialog、ListDialog、ChoiceDialog、GridDialog 和 InputDialog。如果上述类型不能满足需求,还可以通过自定义 DHDialog 来实现。
显示对话框
使用 showDHDialog 方法来显示对话框:
Future<T?> showDHDialog<T>({
required BuildContext context,
required WidgetBuilder builder,
RouteTransitionsBuilder? transitionBuilder,
EntryAnimation entryAnimation = EntryAnimation.none,
Duration? transitionDuration,
Color barrierColor = Colors.black54,
bool barrierDismissible = true,
bool useSafeArea = true,
bool useRootNavigator = true,
});
- entryAnimation 参数用于控制进入动画,已经支持滑动和淡入淡出动画。
关闭对话框
使用 dismissDHDialog 方法关闭对话框:
dismissDHDialog(context);
AlertDialog 示例
DHAlertDialog 是一个简单的对话框,带有标题和内容:
DHAlertDialog(
titleText: "Title",
contentText: "Content",
hasPositive: true, // 是否显示确认按钮
hasNegative: false, // 是否显示取消按钮
positiveTap: () => dismissDHDialog(context), // 点击确认后的回调
)

ListDialog 示例
DHListDialog 是一个列表型对话框,可以用来展示多个选项:
DHListDialog(
titleText: "班级",
titleAlign: TextAlign.center,
hasTitleDivider: true,
datas: [
DialogListItem(TextItem(text: "高一(1)班"), data: "1"),
DialogListItem(TextItem(text: "高一(2)班"), data: "2"),
DialogListItem(TextItem(text: "高一(3)班"), data: "3"),
],
itemAlignment: Alignment.centerLeft,
itemClickListener: (data, position, context) {
print('data: $data, position: $position');
dismissDHDialog(context);
},
dividerColor: Colors.yellow,
itemDividerBuilder: (context, index) => Container(
color: Colors.red,
height: 1.0,
),
hasNegative: false,
hasPositive: false,
actionDividerBuilder: (context, type) {
return Container(
color: Colors.purple,
height: type == DividerType.horizontal ? 1.0 : null,
width: type == DividerType.vertical ? 1.0 : null,
);
},
contentPadding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
dialogMargin: EdgeInsets.zero,
bottomRadius: 0,
topRadius: 10,
);

ChoiceDialog 示例
DHChoiceDialog 是一个多选或单选对话框:
单选示例
List<DialogListItem<ChoiceItem, String>> weeks = [
DialogListItem(
ChoiceItem(
imgWidth: 22,
imgHeight: 22,
text: Selector.all("星期天"),
image: Selector.normal(
normal: '$imagePathPrefix/check_nor.png',
active: '$imagePathPrefix/check_sel.png'),
selected: false),
data: "0"),
DialogListItem(
ChoiceItem(
imgWidth: 22,
imgHeight: 22,
text: Selector.all("星期一"),
image: Selector.normal(
normal: '$imagePathPrefix/check_nor.png',
active: '$imagePathPrefix/check_sel.png'),
selected: false),
data: "1"),
// 其他选项...
];
DHChoiceDialog<ChoiceItem, String>(
titleText: "星期单选",
itemAlignment: Alignment.centerLeft,
datas: weeks,
multiChose: false, // 设置为 false 表示单选
titleDivider: Divider(height: 10, color: Colors.orange),
);

多选示例
将 multiChose 设置为 true 即可实现多选:
DHChoiceDialog<ChoiceItem, String>(
titleText: "星期多选",
itemAlignment: Alignment.centerLeft,
datas: weeks,
multiChose: true,
);

GridDialog 示例
DHGridDialog 是一个网格型对话框,适合展示多个选项:
var datas = [
TextItem(text: '选项1'),
TextItem(text: '选项2'),
TextItem(text: '选项3'),
TextItem(text: '选项4'),
TextItem(text: '选项5'),
TextItem(text: '选项6'),
TextItem(text: '选项7'),
TextItem(text: '选项8'),
TextItem(text: '选项9'),
].mapIndexed((index, e) => DialogListItem(e, data: index))
.toList();
DHGridDialog(
bottomRadius: .0,
topRadius: 10.0,
hasNegative: false,
hasPositive: false,
dialogAlignment: Alignment.bottomCenter,
dialogMargin: EdgeInsets.zero,
titleText: '网格列表',
itemClickListener: (int? data, int position, BuildContext context) {
print('click item $position');
},
datas: datas,
itemBuilder: (
BuildContext context,
TextItem data,
int index, {
BorderRadius? borderRadius,
EdgeInsetsGeometry? padding,
double? height,
AlignmentGeometry? alignment,
GestureTapCallback? onTap,
}) {
return GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(14.0),
decoration: ShapeDecoration(
color: Color(0xFFF5F7FA),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
),
),
child: Image.asset(
'$imagePathPrefix/default_icon.png',
width: 20,
height: 22,
),
),
SizedBox(height: 8.0),
Text(data.text, style: data.textStyle),
],
),
);
},
crossAxisCount: 4,
childAspectRatio: 0.76,
contentPadding: EdgeInsets.only(
left: 10.0,
right: 10.0,
bottom: MediaQuery.of(context).padding.bottom,
),
);

InputDialog 示例
DHInputDialog 是一个带输入框的对话框:
showDHDialog(
entryAnimation: EntryAnimation.slideBottom,
context: context,
builder: (context) {
TextEditingController? editController;
var getter = (controller) => editController = controller;
return DHInputDialog(
titleText: "输入对话框",
filled: true,
style: TextStyle(color: Colors.black, fontSize: 15),
borderStyle: InputBorderStyle.outline,
controllerGetter: getter,
keyboardType: TextInputType.number,
hintText: "请输入用户名",
suffixOnTap: () => editController?.text = "",
suffix: Text(
"删除",
style: TextStyle(color: Colors.pink, fontSize: 12),
),
positiveTap: (result) {
dismissDHDialog(context);
},
negativeTap: (result) {
dismissDHDialog(context);
},
);
},
);

完整示例代码
以下是一个完整的示例代码,展示了如何使用 dh_dialog 插件的各种对话框类型:
import 'package:collection/collection.dart';
import 'package:dh_dialog/dh_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: false,
scaffoldBackgroundColor: Colors.amber,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
List<DialogListItem<ChoiceItem, String>> weeks = [
DialogListItem(
ChoiceItem(
imgWidth: 22,
imgHeight: 22,
text: Selector.all("星期天"),
image: Selector.normal(
normal: '$imagePathPrefix/check_nor.png',
active: '$imagePathPrefix/check_sel.png'),
selected: false),
data: "0"),
// 其他选项...
];
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
onPressed: () {
showDHDialog(
context: context,
builder: (context) {
return DHAlertDialog(
titleText: "Title",
contentText: "Content",
hasPositive: true,
hasNegative: false,
positiveTap: () => dismissDHDialog(context),
);
},
entryAnimation: EntryAnimation.slideBottom,
);
},
child: Text("AlertDialog"),
),
TextButton(
onPressed: () {
showDHDialog(
entryAnimation: EntryAnimation.slideBottom,
context: context,
builder: (context) {
return DHListDialog(
titleText: "班级",
titleAlign: TextAlign.center,
hasTitleDivider: true,
datas: [
DialogListItem(TextItem(text: "高一(1)班"), data: "1"),
DialogListItem(TextItem(text: "高一(2)班"), data: "2"),
DialogListItem(TextItem(text: "高一(3)班"), data: "3"),
],
itemAlignment: Alignment.centerLeft,
itemClickListener: (data, position, context) {
print('data: $data, position: $position');
dismissDHDialog(context);
},
dividerColor: Colors.yellow,
itemDividerBuilder: (context, index) => Container(
color: Colors.red,
height: 1.0,
),
hasNegative: false,
hasPositive: false,
actionDividerBuilder: (context, type) {
return Container(
color: Colors.purple,
height: type == DividerType.horizontal ? 1.0 : null,
width: type == DividerType.vertical ? 1.0 : null,
);
},
contentPadding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom),
dialogMargin: EdgeInsets.zero,
bottomRadius: 0,
topRadius: 10,
);
},
);
},
child: Text("ListDialog"),
),
TextButton(
onPressed: () {
showDHDialog(
entryAnimation: EntryAnimation.slideBottom,
context: context,
builder: (context) {
return DHChoiceDialog<ChoiceItem, String>(
titleText: "星期单选",
itemAlignment: Alignment.centerLeft,
datas: weeks,
multiChose: false,
titleDivider: Divider(height: 10, color: Colors.orange),
);
},
);
},
child: Text("SingleChoiceDialog"),
),
TextButton(
onPressed: () {
showDHDialog(
entryAnimation: EntryAnimation.slideBottom,
context: context,
builder: (context) {
return DHChoiceDialog<ChoiceItem, String>(
titleText: "星期多选",
itemAlignment: Alignment.centerLeft,
datas: weeks,
multiChose: true,
);
},
);
},
child: Text("MultipleChoiceDialog"),
),
TextButton(
onPressed: () {
showDHDialog(
entryAnimation: EntryAnimation.slideBottom,
context: context,
builder: (context) {
TextEditingController? editController;
var getter = (controller) => editController = controller;
return DHInputDialog(
titleText: "输入对话框",
filled: true,
style: TextStyle(color: Colors.black, fontSize: 15),
borderStyle: InputBorderStyle.outline,
controllerGetter: getter,
keyboardType: TextInputType.number,
hintText: "请输入用户名",
suffixOnTap: () => editController?.text = "",
suffix: Text(
"删除",
style: TextStyle(color: Colors.pink, fontSize: 12),
),
positiveTap: (result) {
dismissDHDialog(context);
},
negativeTap: (result) {
dismissDHDialog(context);
},
);
},
);
},
child: Text("InputDialog"),
),
TextButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
var datas = [
TextItem(text: '选项1'),
TextItem(text: '选项2'),
TextItem(text: '选项3'),
TextItem(text: '选项4'),
TextItem(text: '选项5'),
TextItem(text: '选项6'),
TextItem(text: '选项7'),
TextItem(text: '选项8'),
TextItem(text: '选项9'),
].mapIndexed((index, e) => DialogListItem(e, data: index)).toList();
return DHGridDialog(
bottomRadius: .0,
topRadius: 10.0,
hasNegative: false,
hasPositive: false,
dialogAlignment: Alignment.bottomCenter,
dialogMargin: EdgeInsets.zero,
titleText: '网格列表',
itemClickListener: (int? data, int position, BuildContext context) {
print('click item $position');
},
datas: datas,
itemBuilder: (
BuildContext context,
TextItem data,
int index, {
BorderRadius? borderRadius,
EdgeInsetsGeometry? padding,
double? height,
AlignmentGeometry? alignment,
GestureTapCallback? onTap,
}) {
return GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(14.0),
decoration: ShapeDecoration(
color: Color(0xFFF5F7FA),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
),
),
child: Image.asset(
'$imagePathPrefix/default_icon.png',
width: 20,
height: 22,
),
),
SizedBox(height: 8.0),
Text(data.text, style: data.textStyle),
],
),
);
},
crossAxisCount: 4,
childAspectRatio: 0.76,
contentPadding: EdgeInsets.only(
left: 10.0,
right: 10.0,
bottom: MediaQuery.of(context).padding.bottom,
),
);
},
);
},
child: Text('GridDialog'),
),
],
),
),
);
}
}
const String imagePathPrefix = "assets/images";
更多关于Flutter对话框插件dh_dialog的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter对话框插件dh_dialog的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dh_dialog 是一个 Flutter 插件,用于简化对话框的创建和管理。它提供了多种类型的对话框,如确认对话框、提示对话框、加载对话框等。以下是如何使用 dh_dialog 插件的步骤:
1. 添加依赖
首先,在你的 pubspec.yaml 文件中添加 dh_dialog 依赖:
dependencies:
flutter:
sdk: flutter
dh_dialog: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get 来安装依赖。
2. 导入包
在你的 Dart 文件中导入 dh_dialog 包:
import 'package:dh_dialog/dh_dialog.dart';
3. 使用 dh_dialog
3.1 显示确认对话框
确认对话框通常用于让用户确认某个操作,比如删除操作。
DhDialog.confirm(
context,
title: "确认删除",
content: "你确定要删除这条记录吗?",
onConfirm: () {
// 用户点击确认后的操作
print("确认删除");
},
onCancel: () {
// 用户点击取消后的操作
print("取消删除");
},
);
3.2 显示提示对话框
提示对话框通常用于显示一些信息给用户。
DhDialog.alert(
context,
title: "提示",
content: "操作成功!",
onConfirm: () {
// 用户点击确认后的操作
print("确认提示");
},
);
3.3 显示加载对话框
加载对话框通常用于在后台执行耗时操作时显示给用户。
DhDialog.loading(
context,
message: "正在加载...",
);
// 模拟耗时操作
Future.delayed(Duration(seconds: 2), () {
// 关闭加载对话框
Navigator.of(context).pop();
});
3.4 显示自定义对话框
如果你想显示一个自定义的对话框,可以使用 DhDialog.custom。
DhDialog.custom(
context,
builder: (context) {
return AlertDialog(
title: Text("自定义对话框"),
content: Text("这是一个自定义对话框。"),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("关闭"),
),
],
);
},
);
4. 其他功能
dh_dialog 还提供了其他一些功能,比如设置对话框的样式、按钮文本等。你可以查看插件的文档或源代码来了解更多细节。
5. 注意事项
- 确保在使用
dh_dialog时,context是有效的,通常是在build方法中使用。 - 在显示加载对话框时,记得在操作完成后关闭对话框,否则对话框会一直显示。
6. 示例代码
以下是一个完整的示例代码,展示了如何使用 dh_dialog 插件:
import 'package:flutter/material.dart';
import 'package:dh_dialog/dh_dialog.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("dh_dialog 示例"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
DhDialog.confirm(
context,
title: "确认删除",
content: "你确定要删除这条记录吗?",
onConfirm: () {
print("确认删除");
},
onCancel: () {
print("取消删除");
},
);
},
child: Text("显示确认对话框"),
),
ElevatedButton(
onPressed: () {
DhDialog.alert(
context,
title: "提示",
content: "操作成功!",
onConfirm: () {
print("确认提示");
},
);
},
child: Text("显示提示对话框"),
),
ElevatedButton(
onPressed: () {
DhDialog.loading(
context,
message: "正在加载...",
);
Future.delayed(Duration(seconds: 2), () {
Navigator.of(context).pop();
});
},
child: Text("显示加载对话框"),
),
],
),
),
);
}
}

