我自定义了一个Dialog弹窗和BottomSheet弹窗组件,实现App全局调用功能。主要包含以下内容:
- 封装了JudgeDialog类,提供两种弹窗样式:居中Dialog和底部Sheet
- 支持丰富的自定义参数:内容边距、样式、关闭按钮、背景色、透明度等
- 内置了常用配置如圆角边框、按钮样式、文本对齐方式等
- 提供了简单的调用方式,如JudgeDialog.tipDialog(context,content:'支付成功')
- 支持回调函数处理确认/取消操作,并可以完全控制弹窗关闭行为
该组件封装了常见的弹窗交互需求,简化了开发流程,使弹窗调用更加便捷统一。
class JudgeDialog {
// 内容边距
static EdgeInsetsGeometry _contentPadding(String? content) {
return content != null
? EdgeInsets.only(
left: 30.rpx,
right: 30.rpx,
top: 32.rpx,
bottom: 26.rpx,
)
: EdgeInsets.all(0.rpx);
}
// 内容样式
static TextStyle _contentStyle() {
return TextStyle(
fontSize: 31.rpx,
height: 1.5,
fontFamily: AppTextFamily.appleMiddle,
color: AppColors.t3,
);
}
// X关闭按钮
static Widget closeBtn(
BuildContext context, {
Function? closeCall,
}) {
return Positioned(
right: 36.rpx,
top: 30.rpx,
child: SizedBox(
height: 36.rpx,
width: 36.rpx,
child: IconButton(
onPressed: () {
if (closeCall != null) {
closeCall();
} else {
Navigator.pop(context);
}
},
padding: EdgeInsets.all(0.rpx),
icon: Transform.rotate(
angle: pi / 4,
child: Icon(
AppIcon.plusAdd,
size: 36.rpx,
color: AppColors.t9,
),
),
),
),
);
}
static Future<bool?> tipDialog(
BuildContext context, {
bool? dismissible = false, // 背景与滑动是否可关
bool? close = false, // 是否有X的关闭
Function? closeCall, // 关闭X时调用
Color? bgColor, // 背景色
double? opacity,
String? title,
String? content,
Widget? contentChild,
EdgeInsetsGeometry? contentPadding,
TextAlign? textAlign,
double? btnWidth,
String? confirmText = '我知道了',
Function? confirm,
String? cancelText = '取消',
Function? cancel,
}) async {
return showDialog(
context: context,
barrierDismissible: dismissible!,
barrierColor: bgColor ?? Colors.black.withOpacity(opacity ?? 0.55),
builder: (dialogContext) {
return WillPopScope(
onWillPop: () async {
return dismissible;
},
child: Container(
width: HYSizeFit.screenWidth,
padding: EdgeInsets.only(
left: HYSizeFit.screenWidth * 0.1,
right: HYSizeFit.screenWidth * 0.1,
bottom: HYSizeFit.screenHeight * 0.1,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
AlertDialog(
insetPadding: EdgeInsets.all(0.rpx),
backgroundColor: Colors.white,
titlePadding: EdgeInsets.all(0.rpx),
buttonPadding: EdgeInsets.all(0.rpx),
alignment: Alignment.center,
elevation: 0.rpx,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.rpx), // 设置圆角大小
),
title: Stack(
children: [
Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 52.rpx),
child: AppTextTitle.titleH34(
title ?? '提示',
fontFamily: AppTextFamily.appleBold,
),
),
if (close!)
closeBtn(
dialogContext,
closeCall: closeCall,
),
],
),
contentPadding: contentPadding ?? _contentPadding(content),
contentTextStyle: _contentStyle(),
content: content != null
? Text(content, textAlign: textAlign ?? TextAlign.center)
: contentChild ?? const SizedBox.shrink(),
actionsAlignment: MainAxisAlignment.spaceAround,
actionsPadding: EdgeInsets.only(
top: content != null ? 26.rpx : 0.rpx,
left: 30.rpx,
right: 30.rpx,
bottom: 52.rpx,
),
actions: [
if (cancel != null)
GlobalButton.customButton(
'$cancelText',
bgColor1: AppColors.page,
bgColor2: AppColors.page,
color: AppColors.t3,
width: btnWidth ?? 210.rpx,
height: 70.rpx,
radius: 35.rpx,
size: 30.rpx,
ripple: false,
onPressed: () => cancel(),
),
GlobalButton.customButton(
'$confirmText',
bgColor1: AppColors.primary,
bgColor2: AppColors.primary,
width: btnWidth ?? 210.rpx,
height: 70.rpx,
radius: 35.rpx,
size: 30.rpx,
ripple: false,
onPressed: () {
if (confirm == null) {
Navigator.pop(context, true);
} else {
confirm();
}
},
),
],
),
],
),
),
);
},
);
}
// 自定义弹窗
static Future<bool?> markDialog(
BuildContext context, {
bool? dismissible = false,
double? opacity,
Color? bgColor, // 背景色
required Widget child,
}) async {
return showDialog(
context: context,
barrierDismissible: dismissible!,
barrierColor: bgColor ?? Colors.black.withOpacity(opacity ?? 0.55),
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
return dismissible;
},
child: SizedBox(
width: HYSizeFit.screenWidth,
height: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [child],
),
),
);
},
);
}
/// 底部弹窗
static Future<bool?> modalSheet(
BuildContext context, {
bool? dismissible = true,
double? opacity,
Color? barrierColor, // 弹窗背景色
Color? bgColor, // 弹出背景
double? elevation,
BoxConstraints? constraints,
required Widget child,
}) async {
return showModalBottomSheet(
context: context,
elevation: elevation,
constraints: constraints,
backgroundColor: bgColor ?? Colors.transparent,
barrierColor: barrierColor ?? Colors.black.withOpacity(opacity ?? 0.6),
builder: (BuildContext context) {
return child;
},
);
}
}
使用很简单:
JudgeDialog.tipDialog(context, content: '支付成功');
这样也相当方便。