HarmonyOS鸿蒙Next中如何使用openCustomDialog禁止手势关闭的实现方案?提供源码和方案思路

HarmonyOS鸿蒙Next中如何使用openCustomDialog禁止手势关闭的实现方案?提供源码和方案思路

如何使用openCustomDialog禁止手势关闭的实现方案?提供源码和方案思路

3 回复

一、结论

图片

要实现禁止手势 / 外部点击关闭弹窗,核心依赖两个关键配置: 1、autoCancel 参数: 控制点击弹窗外部遮障层是否触发关闭,设置为 false 可直接禁用该关闭方式。

2、onWillDismiss 回调: 弹窗关闭前的拦截钩子,通过 DismissReason 枚举判断关闭原因,返回 false 可阻止弹窗关闭。

3、DismissReason 关键枚举值: PRESS_BACK:点击三键 back、侧滑(左滑 / 右滑)、键盘 ESC 触发的关闭; TOUCH_OUTSIDE:点击弹窗遮障层(外部区域)触发的关闭; CLOSE_BUTTON:点击弹窗内关闭按钮触发的关闭; 其他枚举(SLIDE_DOWN、SLIDE):适配半模态转场的滑动关闭场景

二、代码实现和详细解释

1、基础配置:禁用外部点击+拦截手势关闭 核心逻辑是通过autoCancel禁用外部点击关闭,再利用onWillDismiss回调根据DismissReason拦截手势/返回键关闭,仅放行主动操作(如按钮点击)。

import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct DialogCloseTestPage {
  private customDialogComponentId: number = 0;

  @Builder
  customDialogComponent() {
    Column() {
      Text('弹窗内容区域Blablabla..').fontSize(20)
      Row({ space: 10 }) {
        Button('取消').onClick(() => {
          try {
            this.getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId)
          } catch (error) {
            let message = (error as BusinessError).message;
            let code = (error as BusinessError).code;
            console.error(`closeCustomDialog error code is ${code}, message is ${message}`);
          }
        }).width(100).backgroundColor('#d5d5d5').fontColor('#707070')
        Button('确定').onClick(() => {
          try {
            this.getUIContext().getPromptAction().closeCustomDialog(this.customDialogComponentId)
          } catch (error) {
            let message = (error as BusinessError).message;
            let code = (error as BusinessError).code;
            console.error(`closeCustomDialog error code is ${code}, message is ${message}`);
          }
        }).width(100)
      }
    }.height(150).padding(20).justifyContent(FlexAlign.SpaceBetween)
  }

  build() {
    Column() {
      Button('禁止手势关闭弹窗')
        .margin({
          top: 100
        })
        .fontSize(30)
        .onClick(() => {
          this.getUIContext()
            .getPromptAction()
            .openCustomDialog({
              builder: () => {
                this.customDialogComponent()
              },
              onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
                console.info('reason' + JSON.stringify(dismissDialogAction.reason));
                console.info('dialog onWillDismiss');
                // 返回手势
                if (dismissDialogAction.reason == DismissReason.PRESS_BACK) {
                  // dismissDialogAction.dismiss();
                }
                // 点击弹窗以外区域
                if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) {
                  // dismissDialogAction.dismiss();
                }
              }
            })
            .then((dialogId: number) => {
              this.customDialogComponentId = dialogId;
            })
            .catch((error: BusinessError) => {
              console.error(`openCustomDialog error code is ${error.code}, message is ${error.message}`);
            })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Start)
  }
}

关键参数说明:

枚举名称 数值 描述 说明 元服务API支持版本
PRESS_BACK 0 点击三键back、侧滑(左滑/右滑)、键盘ESC。 - 从API version 12开始支持在元服务中使用
TOUCH_OUTSIDE 1 点击遮障层时。 - 从API version 12开始支持在元服务中使用
CLOSE_BUTTON 2 点击关闭按钮。 - 从API version 12开始支持在元服务中使用
SLIDE_DOWN 3 下拉关闭。 该接口仅支持在半模态转场中使用。 从API version 12开始支持在元服务中使用
SLIDE 4 侧滑(左滑/右滑)关闭。默认表示向右滑动关闭,镜像场景表示向左滑动关闭,不支持选择向左或向右滑动。 该接口仅支持在半模态转场中使用。 从API version 20开始支持在元服务中使用

引用资料地址

1、鸿蒙PromptAction官方文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-promptaction#promptactionopentoast18 2、鸿蒙自定义弹窗最佳实践:https://developer.huawei.com/consumer/cn/doc/architecture-guides/architecture-v1-3_2-ts_90-0000002444269041 3、鸿蒙页面返回键拦截:https://developer.huawei.com/consumer/cn/forum/topic/0201188750103330725?fid=0109140870620153026

更多关于HarmonyOS鸿蒙Next中如何使用openCustomDialog禁止手势关闭的实现方案?提供源码和方案思路的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,使用openCustomDialog禁止手势关闭需设置customStyletrue并禁用相关属性。示例代码如下:

import { promptAction } from '@kit.ArkUI';

promptAction.openCustomDialog({
  customStyle: true,
  alignment: DialogAlignment.Bottom,
  mask: { color: '#000000', opacity: 0.5 },
  // 关键设置:禁用滑动关闭
  gestureBehavior: GestureBehavior.None,
  builder: (controller) => {
    // 自定义弹窗内容
    return YourCustomComponent();
  }
});

方案思路:通过gestureBehavior: GestureBehavior.None参数直接禁用滑动手势交互,同时确保customStyletrue以启用自定义控制。

在HarmonyOS Next中,可以通过设置openCustomDialogautoCancel属性为false来禁止手势关闭弹窗。以下是具体实现方案和源码示例:

方案思路:

  1. 使用CustomDialogController创建自定义弹窗控制器。
  2. 在弹窗控制器的构造参数中,将autoCancel设置为false,这将禁用点击弹窗外部区域和手势返回关闭弹窗的行为。
  3. 通过自定义的关闭按钮来控制弹窗关闭。

源码示例:

// 自定义弹窗组件
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController

  build() {
    Column() {
      Text('这是一个禁止手势关闭的弹窗')
        .fontSize(20)
        .margin(20)

      Button('关闭弹窗')
        .onClick(() => {
          this.controller.close()
        })
        .margin(10)
    }
    .padding(20)
    .backgroundColor(Color.White)
    .borderRadius(10)
  }
}

// 在页面中使用
@Entry
@Component
struct Index {
  // 创建弹窗控制器,设置autoCancel为false
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
    autoCancel: false, // 关键设置:禁止手势和外部点击关闭
    alignment: DialogAlignment.Center,
    customStyle: true
  })

  build() {
    Column() {
      Button('打开弹窗')
        .onClick(() => {
          this.dialogController.open()
        })
    }
    .width('100%')
    .height('100%')
  }
}

关键说明:

  • autoCancel: false 参数同时禁用了:
    1. 点击弹窗外部区域关闭
    2. 手势返回操作关闭
    3. 物理返回键关闭
  • 弹窗关闭必须通过代码显式调用controller.close()方法
  • 此方案适用于需要用户必须进行确认操作的场景,如重要确认对话框、表单填写等

注意事项:

  • 当设置autoCancel: false时,务必提供明确的关闭途径(如确认/取消按钮)
  • 弹窗内容区域需要合理设计,确保用户体验
  • 在平板或折叠屏设备上,需要考虑大屏幕适配
回到顶部