HarmonyOS 角落里的知识 —— 触摸交互

518 阅读3分钟

一、前言

在探索 HarmonyOS 的过程中,我们发现了许多有趣且实用的功能和特性。有些总是在不经意间或者触类旁通的找到。或者是某些开发痛点。其中,触摸交互是手机上逃无可逃、避无可避的,需要了解的东西,这也是我们在处理多重嵌套组件时了解到的东西。

该系列将着重分享、介绍HarmonyOS API11+的新版本特性或者奇奇怪怪的解决方案、BUG。(弃用API非必要不提及)

如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏

二、触摸热区

responseRegion(value: Array<Rectangle> | Rectangle)

在Android中,如果想一个控件的事件响应大于它本身,可以是使用Padding来扩大一个透明的区域。但是如果这个控件大小影响到了当前布局,使用Padding就不合适了。这时一般是选择重写当前页面的onTouchEvent,Java使用一个触摸代理解决,Kotlin也是如此,不过可以充分利用语法糖来简化代码。

HarmonyOS提供了一个API:responseRegion ,使用起来非常的简单:

 Button("Button")
   .responseRegion({ x: '-100%', y: '-100%', width: '300%', height: '300%' })
   .onClick(() => {
     
   })

image-20240522145240139

从API的参数来看,接收一个Rectangle数组,所以区域的设置可以是漫天乱跑的。

Rectangle构造如下:

xLength触摸点相对于组件左上角的x轴坐标。默认值:0vp
yLength触摸点相对于组件左上角的y轴坐标。默认值:0vp
widthLength触摸热区的宽度。默认值:'100%'
heightLength触摸热区的高度。默认值:'100%'

需要注意是的是:x、y是从组件自身左上角开始的,所以如果你需要扩充一倍的点击区域那就是如此:{ x: '-100%', y: '-100%', width: '300%', height: '300%' }

三、触摸测试控制

hitTestBehavior(value: HitTestMode)

这个发现,其实也是因为使用触摸热区的时候,发现热区不生效,查来查去发现是Stack中的叠加。

因为在ArtkUI中,当Stack组件中有多个节点触摸区域重叠时,如两个节点,默认只会对显示在最上层的节点做触摸测试,若需要显示在下层的节点触发触摸测试(原话)。

所以出现这种情况的时候,需要给上层的节点设置hitTestBehavior为HitTestMode.Transparent。

 Stack() {
    Button('Fuck')
      .onTouch((event) => {
        
      })
  }
  .width("100%").height("100%")
  .hitTestBehavior(HitTestMode.Block)
  .onTouch((event) => {
   
  })

我是很迷糊的,因为Android写多了,感觉我没给组件设置事件凭什么拦截啊,现在写多了HarmonyOS也就习惯了。

HitTestMode目前也只有四种:

Default0默认触摸测试效果,自身和子节点都响应触摸测试,但会阻塞兄弟节点的触摸测试。
Block1自身响应触摸测试,阻塞子节点和兄弟节点的触摸测试。
Transparent2自身和子节点都响应触摸测试,不会阻塞兄弟节点的触摸测试。
None3自身不响应触摸测试,不会阻塞子节点和兄弟节点的触摸测试。

为什么要叫触摸测试呢?不懂。

四、事件独占控制

monopolizeEvents(monopolize: boolean)

顾名思义。”在一个窗口内,设置了独占控制的组件上的事件如果首先响应,则本次交互只允许此组件上设置的事件响应,窗口内其他组件上的事件不会响应。“

一般来说用在复杂的事件逻辑中的,或者图片操作啥的。

六、预告

下篇分享@State、@Prop、@Provide、@ObjectLink、@ObjectLinkV2、@Link、@Watch、@Track(可能)

七、结尾

没了。

如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏