HarmonyOS鸿蒙Next中customDialog弹框事件穿透问题

HarmonyOS鸿蒙Next中customDialog弹框事件穿透问题

customDialog弹框内容能否实现事件穿透?

4 回复

感谢提问,为了更快的解决您的问题,请将问题描述清晰,让答题者们可以更快更清晰地理解您的问题。

  • 背景说明:问题场景描述
  • 问题现象:具体报错信息,异常信息(尽可能文本或则截图说明)。
  • 版本信息:开发工具版本、手机系统版本、Api语言版本
  • 已尝试方案:列出已尝试的解决方案及测试结果

更多提问技巧,请参考:【Tips】如何提个好问题

更多关于HarmonyOS鸿蒙Next中customDialog弹框事件穿透问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


当前版本customDialog不支持事件穿透,自定义的内容buidler会被放入一个column中,在builder中使用hitTestBehavior(HitTestMode.None)无法阻止这个column拦截事件

解决方法:

  1. 设置isModal为false关闭蒙层(蒙层会拦截事件)
  2. 设置customStyle为true控制dialog内容大小不要延伸到事件可穿透的区域

代码参考:

@CustomDialog
struct CustomDialogExample {
  controller?: CustomDialogController

  build() {
    Column() {
      Button('关闭')
        .onClick(() => {
          this.controller?.close()
        })
    }
    .borderWidth(1)
    .backgroundColor(Color.Grey)
    .width('100%')
    .height('80%') // 自定义弹框的大小,不覆盖全屏, 预留弹框上方空间可响应事件
  }
}

@Entry
@Component
struct CustomDialogUser {
  @State count: number = 0

  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExample(),
    alignment: DialogAlignment.Bottom,
    isModal: false, // 蒙层会拦截事件,设置isModal为false 可不显示蒙层
    customStyle: true,  // 自定义弹框样式,手动控制builder中弹框内容的大小
  })

  aboutToDisappear() {
    this.dialogController = null
  }

  build() {
    Column() {
      Button(`点击次数: ${this.count}`)
        .onClick(() => { this.count++ })
        .margin(10)

      Button('open Dialog')
        .onClick(() => {
          if (this.dialogController != null) {
            this.count = 100
            this.dialogController.open()
          }
        })
    }.width('100%').margin({ top: 5 })
  }
}

在HarmonyOS鸿蒙Next中,customDialog弹框事件穿透问题通常是由于弹框的遮罩层未正确处理事件拦截导致的。可以通过设置弹框的modal属性为true来确保遮罩层拦截事件,防止事件穿透到下层组件。此外,检查弹框的touchable属性,确保其值为false,以避免弹框自身响应触摸事件。若问题依旧存在,需检查弹框的层级关系,确保弹框位于最上层。

在HarmonyOS Next中,CustomDialog默认会拦截下层组件的事件响应。要实现事件穿透,可以通过以下两种方式:

  1. 设置dialog的modal属性为false:
customDialog.show({
  modal: false,  // 关键设置
  // 其他配置项
})
  1. 在ArkUI中使用hitTestBehavior设置穿透:
Column() {
  // 弹框内容
}
.hitTestBehavior(HitTestMode.Transparent)  // 允许事件穿透

这两种方式都能让下层组件继续响应点击等事件,但需要注意事件穿透可能带来的交互逻辑冲突问题。

回到顶部