Flutter 自定义Dialog弹窗和BottomSheet弹窗

 我自定义了一个Dialog弹窗和BottomSheet弹窗组件,实现App全局调用功能。主要包含以下内容:

  1. 封装了JudgeDialog类,提供两种弹窗样式:居中Dialog和底部Sheet
  2. 支持丰富的自定义参数:内容边距、样式、关闭按钮、背景色、透明度等
  3. 内置了常用配置如圆角边框、按钮样式、文本对齐方式等
  4. 提供了简单的调用方式,如JudgeDialog.tipDialog(context,content:'支付成功')
  5. 支持回调函数处理确认/取消操作,并可以完全控制弹窗关闭行为

该组件封装了常见的弹窗交互需求,简化了开发流程,使弹窗调用更加便捷统一。

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: '支付成功');

 这样也相当方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值