HarmonyOS鸿蒙Next中多层级布局,上层手势事件如何透传到下层控件

HarmonyOS鸿蒙Next中多层级布局,上层手势事件如何透传到下层控件

【问题现象】

由于需要做视频播控手势,以下代码无法通过手势滑动屏幕控制音量、亮度和进度。

Stack() {
  Column() {
    // 组件B
  }
  .gesture(PanGesture()) // 期望能够透传到这个地方
  Column() {
    // 组件C,内部包含DEF三个组件,期望能够把这个手势事件透传给上边的组件
    Blank()
      .parallelGesture(null, GestureMask.IgnoreInternal) 
    this.bottom()
  }
  .parallelGesture(null, GestureMask.IgnoreInternal)
}

如下层叠布局:B组件表示音量控制、亮度等下层组件,D/E/F表示上层组件。

点击放大

预期效果:组件D、E、F上的手势操作能够透传到B组件上控制音量、亮度变化等操作,而不执行C、D、E、F上的手势操作。

实际问题:手势操作只在上层D、E、F 组件上适配,无法将手势操作透传给下层目标组件B。

【背景知识】

通过设置属性hitTestBehavior控制多层级手势事件竞争流程。

  • HitTestMode.Transparent:自身响应触摸测试,不会阻塞兄弟节点的触摸测试
  • HitTestMode.Block:自身会响应触摸测试,阻塞子节点和兄弟节点的触摸测试,从而导致子节点和兄弟节点的onTouch事件和手势均无法触发
  • HitTestMode.None:自身不响应触摸测试,不会阻塞子节点和兄弟节点的触摸控制

【解决方案】

针对业务场景代码梳理UI层级,预期将上层手势响应事件不作处理透传到下层组件进行处理,根据hitTestBehavior类型说明,选择HitTestMode.None模式,达到上层不响应,传递至子节点响应。

上述场景实现代码:

@Component
struct Index {
  build() {
    Stack() {
      Column() {
        ComponentB()
          .onTouch(() => {
            console.log('Executing a gesture:ComponentB');
          })
          .gesture(TapGesture({ count: 1 }))
          .backgroundColor(Color.Green)
          .width('90%')
          .height('90%')
      }

      // 组件C设置.hitTestBehavior(HitTestMode.None),自身不响应触摸测试
      ComponentC()
        .onTouch(() => {
          console.log('Executing a gesture:ComponentC');
        })
        .gesture(TapGesture({ count: 1 }))
        .backgroundColor(Color.Blue)
        .width('80%')
        .height('80%')
        .hitTestBehavior(HitTestMode.None)
    }
    .onTouch(() => {
      console.log('Executing a gesture:StackA');
    })
    .gesture(TapGesture({ count: 1 }))
    .backgroundColor(Color.Gray)
    .width('100%')
    .height('100%')
    .hitTestBehavior(HitTestMode.None)
  }
}

@Component
struct ComponentC {
  build() {
    Flex({ direction: FlexDirection.Column }) {
      ComponentD()
        .onTouch(() => {
          console.log('Executing a gesture:ComponentD');
        })
        .gesture(TapGesture({ count: 1 }))
        .backgroundColor(Color.Yellow)
        .height('30%')
        .width('100%')

      // 组件E设置.hitTestBehavior(HitTestMode.None),自身不响应触摸测试
      ComponentE()
        .onTouch(() => {
          console.log('Executing a gesture:ComponentE');
        })
        .gesture(TapGesture({ count: 1 }))
        .backgroundColor(Color.Pink)
        .height('30%')
        .width('100%')
        .hitTestBehavior(HitTestMode.None)
      ComponentF()
        .onTouch(() => {
          console.log('Executing a gesture:ComponentF');
        })
        .gesture(TapGesture({ count: 1 }))
        .backgroundColor(Color.Red)
        .height('30%')
        .width('100%')
    }.width('100%').height('100%')
    .hitTestBehavior(HitTestMode.None)
  }
}

手势传递结果验证:

触摸D区域:
 Executing a gesture:ComponentD
 Executing a gesture:ComponentB

触摸E区域:
 Executing a gesture:ComponentB

触摸F区域:
 Executing a gesture:ComponentF
 Executing a gesture:ComponentB

触摸C区域:
 Executing a gesture:ComponentB

触摸B区域:
 Executing a gesture:ComponentB

触摸A区域:
 // 无相关日志打印

【总结】

多层级UI布局手势操作,需要于设计过程中梳理对应的手势响应操作,hitTestBehavior属性可以实现在复杂的多层级场景下决定哪些组件可以响应手势和事件,完成业务场景中的手势传递。


更多关于HarmonyOS鸿蒙Next中多层级布局,上层手势事件如何透传到下层控件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中多层级布局,上层手势事件如何透传到下层控件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,通过设置hitTestBehavior属性为HitTestMode.None,可以实现上层手势事件透传到下层控件。具体实现如下:

  1. 组件C设置hitTestBehavior(HitTestMode.None)

    ComponentC()
      .hitTestBehavior(HitTestMode.None)
    
  2. 组件E设置hitTestBehavior(HitTestMode.None)

    ComponentE()
      .hitTestBehavior(HitTestMode.None)
    
  3. 组件F设置hitTestBehavior(HitTestMode.None)

    ComponentF()
      .hitTestBehavior(HitTestMode.None)
    

通过以上设置,上层组件D、E、F上的手势操作能够透传到下层组件B,实现控制音量、亮度等操作。

回到顶部