触摸测试控制

设置组件的触摸测试类型。在ArkUI开发框架中,处理触屏事件和鼠标事件时,会在事件触发前进行按压点与组件响应热区的触摸测试,以收集需响应事件的组件。基于测试结果,框架会分发相应的事件。hitTestBehavior属性用于设置不同的触摸测试响应模式,影响触摸测试收集结果及后续事件分发。具体影响参考HitTestMode枚举说明。影响点击事件触摸事件拖拽事件鼠标事件轴事件悬浮事件无障碍悬浮事件手势事件的分发。

说明:

  • 本模块首批接口从API version 9开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。

  • 当Stack组件中有多个节点触摸区域重叠时,如果最上层节点的子组件命中,则默认只会对显示在最上层的节点做触摸测试。此时只有给显示在最上层的节点设置hitTestBehavior为HitTestMode.Transparent时,才能使显示在下层的节点触发触摸测试。

  • 存在新增节点时,如需该节点响应触摸测试,需要对其设置HitTestMode。当新增节点存在多层级节点时,仅需设置根节点的HitTestMode。

hitTestBehavior

hitTestBehavior(value: HitTestMode): T

设置组件的触摸测试类型。如果组件不设置hitTestBehavior,其默认触摸测试类型为HitTestMode.Default。

卡片能力: 从API版本26.0.0开始,该接口支持在ArkTS卡片中使用。

原子化服务API: 从API version 11开始,该接口支持在原子化服务中使用。

系统能力: SystemCapability.ArkUI.ArkUI.Full

参数:

参数名 类型 必填 说明
value HitTestMode 设置当前组件的触摸测试类型。

返回值:

类型 说明
T 返回当前组件。

示例

示例1(触摸测试类型为Block和Transparent的触摸测试效果)

该示例通过设置不同的HitTestMode值演示了Block和Transparent的触摸测试效果。

// xxx.ets
@Entry
@Component
struct HitTestBehaviorExample {
  build() {
    // outer stack
    Stack() {
      Button('outer button')
        .onTouch((event) => {
          console.info(`outer button touched type: ${(event as TouchEvent).type}`)
        })
      // inner stack
      Stack() {
        Button('inner button')
          .onTouch((event) => {
            console.info(`inner button touched type: ${(event as TouchEvent).type}`)
          })
      }
      .width("100%").height("100%")
      .hitTestBehavior(HitTestMode.Block)
      .onTouch((event) => {
        console.info(`stack touched type: ${(event as TouchEvent).type}`)
      })

      Text('Transparent')
        .hitTestBehavior(HitTestMode.Transparent)
        .width("100%").height("100%")
        .onTouch((event) => {
          console.info(`text touched type: ${(event as TouchEvent).type}`)
        })
    }.width(300).height(300)
  }
}

示例2(触摸测试类型为BLOCK_HIERARCHY时的触摸测试效果)

从API version 20开始,该示例演示了设置触摸测试类型为BLOCK_HIERARCHY时的触摸测试效果。

// xxx.ets
@Entry
@Component
struct BlockHierarchy {
  build() {
    // outer stack
    Stack() {
      Stack() {
        Button('outer button')
          .onTouch((event) => {
            console.info(`HitTestMode outer button touched type: ${(event as TouchEvent).type}`);
          })
          .width(200)
          .height(200)
          .backgroundColor('#D5D5D5')
        // inner stack
        Stack() {
          Button()
            .id('button150')
            .backgroundColor('#F7F7F7')
            .width(150)
            .height(150)
            .onTouch((event) => {
              console.info(`HitTestMode button150 touched type: ${(event as TouchEvent).type}`);
            })
            .hitTestBehavior(HitTestMode.Transparent)
          Button()
            .id('button100')
            .backgroundColor('#707070')
            .width(100)
            .height(100)
            .onTouch((event) => {
              console.info(`HitTestMode button100 touched type: ${(event as TouchEvent).type}`);
            })
            .hitTestBehavior(HitTestMode.Transparent)
          Button()
            .id('button050')
            .backgroundColor('#D5D5D5')
            .width(50)
            .height(50)
            .onTouch((event) => {
              console.info(`HitTestMode button050 touched type: ${(event as TouchEvent).type}`);
            })
            .hitTestBehavior(HitTestMode.Transparent)
        }
        .width("100%").height("100%")
        // 设置触摸测试模式,自身和子节点响应触摸测试,阻止所有优先级较低的兄弟节点和父节点参与触摸测试
        .hitTestBehavior(HitTestMode.BLOCK_HIERARCHY)
        .onTouch((event) => {
          console.info(`HitTestMode stack touched type: ${(event as TouchEvent).type}`);
        })

        Text('Transparent')
          .hitTestBehavior(HitTestMode.Transparent)
          .width("100%").height("100%")
          .onTouch((event) => {
            console.info(`HitTestMode text touched type: ${(event as TouchEvent).type}`);
          })
      }.width(300).height(300)
      .borderWidth(2)
      .onTouch((event) => {
        console.info(`HitTestMode father stack touched type: ${(event as TouchEvent).type}`);
      })
    }.width(500).height(500)
    .borderWidth(2)
    .onTouch((event) => {
      console.info(`HitTestMode grandfather stack touched type: ${(event as TouchEvent).type}`);
    })
  }
}

示例3(触摸测试类型为BLOCK_DESCENDANTS时的触摸测试效果)

从API version 20开始,该示例演示了设置触摸测试类型为BLOCK_DESCENDANTS时的触摸测试效果。

// xxx.ets
@Entry
@Component
struct BlockDescendants {
  build() {
    // outer stack
    Stack() {
      Stack() {
        Button('outer button')
          .onTouch((event) => {
            console.info(`HitTestMode outer button touched type: ${(event as TouchEvent).type}`);
          })
          .width(200)
          .height(200)
          .backgroundColor('#D5D5D5')
        // inner stack
        Stack() {
          Button('inner button')
            .width(100)
            .height(100)
            .onTouch((event) => {
              console.info(`HitTestMode inner button touched type: ${(event as TouchEvent).type}`);
            })
        }
        .width("100%").height("100%")
        // 设置触摸测试模式,自身不响应触摸测试,并且所有的后代(孩子,孙子等)也不响应触摸测试
        .hitTestBehavior(HitTestMode.BLOCK_DESCENDANTS)
        .onTouch((event) => {
          console.info(`HitTestMode stack touched type: ${(event as TouchEvent).type}`);
        })

        Text('Transparent')
          .hitTestBehavior(HitTestMode.Transparent)
          .width("100%").height("100%")
          .onTouch((event) => {
            console.info(`HitTestMode text touched type: ${(event as TouchEvent).type}`);
          })
      }.width(300).height(300)
      .borderWidth(2)
      .onTouch((event) => {
        console.info(`HitTestMode father stack touched type: ${(event as TouchEvent).type}`);
      })
    }.width(500).height(500)
    .borderWidth(2)
    .onTouch((event) => {
      console.info(`HitTestMode grandfather stack touched type: ${(event as TouchEvent).type}`);
    })
  }
}

示例4(Stack组件中多节点重合时的触摸测试效果)

该示例演示了在Stack组件中存在多节点触摸区域重叠时的触摸测试效果。此时设置HitTestMode为None时,重叠的背景区域无法响应触摸测试;只有设置为Transparent时,背景区域才能响应触摸测试。

// xxx.ets
@Entry
@Component
struct Index {
  @State @Watch('onModeChange') mode: number = HitTestMode.None;
  @State modeStr: string = 'None';

  onModeChange() {
    this.modeStr = this.mode === HitTestMode.None ? 'None' : 'Transparent';
  }

  build() {
    Stack() {
      Column()
        .height('100%')
        .width('100%')
        .onTouch(() => {
          console.info('background hit test!')
        })
      Stack() {
        // 点击按钮进行触摸测试
        Button('HitTest')
        // 点击按钮切换不同的触摸测试模式
        Button('HitTestMode: ' + this.modeStr)
          .margin({ top: 100 })
          .onClick(() => {
            this.mode = this.mode === HitTestMode.None ?
              HitTestMode.Transparent : HitTestMode.None;
          })
      }
      .height('100%')
      .width('100%')
      // 只有上层节点的HitTestMode设置为Transparent时,下层节点才能响应触摸测试
      .hitTestBehavior(this.mode)
    }
    .height('100%')
    .width('100%')
  }
}