[经验分享] OpenHarmony应用组件自定义手势判定 原创

深开鸿_张守忠 显示全部楼层 发表于 2024-1-16 19:59:18

简介:

为组件绑定不同类型的手势事件,并设置事件的响应方法。 通过如下属性给组件绑定手势识别,手势识别成功后可以通过事件回调通知组件。

名称 参数类型 默认值 描述
gesture gesture: GestureType, mask?: GestureMask gesture: -,mask: GestureMask.Normal 绑定手势。- gesture: 绑定的手势类型。 - mask: 事件响应设置。
priorityGesture gesture: GestureType, mask?: GestureMask gesture: -,mask: GestureMask.Normal 绑定优先识别手势。- gesture: 绑定的手势类型。- mask: 事件响应设置。1、默认情况下,子组件优先识别通过gesture绑定的手势,当父组件配置priorityGesture时,父组件优先识别priorityGesture绑定的手势。2、长按手势时,设置触发长按的最短时间小的组件会优先响应,会忽略priorityGesture设置。
parallelGesture gesture: GestureType, mask?: GestureMask gesture: -,mask: GestureMask.Normal 绑定可与子组件手势同时触发的手势。- gesture: 绑定的手势类型。 - mask: 事件响应设置。手势事件为非冒泡事件。父组件设置parallelGesture时,父子组件相同的手势事件都可以触发,实现类似冒泡效果。若父子组件中同时绑定单击手势事件和双击手势事件,则只响应单击手势事件。

文档环境:

  • 开发环境:Windows 10专业版
  • DevEco Studio版本:DevEco Studio 4.0Release (4.0.0.600)
  • SDK版本:4.1.6.1 (full sdk)
  • API版本:Version 11
  • 开发板型号:DAYU200(RK3568)
  • 系统版本:OpenHarmony 4.1.6.1

演示demo:

  • 新建一个 Stage 框架的 demo 工程,在page/Index.ets中通过两个stack组件分别封装colunm和text组件,其中上半部分背景色为蓝色,下半部分为黄色。
  • 上下两部分的stack分别绑定tap和longpress手势,通过属性onGestureJudgeBegin判定用户手势类型,对于上半部分只有在手势类型为longpress时通知上半部分的stack组件响应,而下半部分只有在手势类型为tap时通知下半部分stack组件响应。

demo运行效果:

首页 长按蓝色区域 点击黄色区域
image image image

核心代码如下:

import ShowToast from 'ShowToast';

@Entry
@Component
struct CustomJudgeEvent {
  private btnFontColor: Resource = $r('app.color.white');
  @State message: string = '';

  build() {
    Column() {
      // 上半部分
      Stack() {
        Column() {
        }
        .height(340)
        .width('100%')
        .backgroundColor('#007DFF')
        .opacity(0.1)
        .alignItems(HorizontalAlign.Center)
        .justifyContent(FlexAlign.Center)
        .id('longPressColumn')
        .border({
          width: 1,
          color: '#007DFF',
          radius: { topLeft: 24, topRight: 24, bottomLeft: 0, bottomRight: 0 },
          style: BorderStyle.Dotted
        })

        Text($r('app.string.custom_judge_long_press'))
          .fontSize(16)
          .fontWeight(400)
          .fontFamily(' HarmonyHeiTi')
          .textAlign(TextAlign.Center)
          .opacity(0.7)
          .fontColor('#007DFF')
          .id('longPressPrompt')
      }
      .id('longPressArea')
      .gesture(
        TapGesture()
          .tag("tap1")
      )
      .gesture(
        LongPressGesture()
          .tag("longPress1")
          .onAction(() => {
            this.message = 'longPress';
            ShowToast.longToast($r('app.string.custom_long_press_prompt'));
          })
      )
      .onGestureJudgeBegin((gestureInfo: GestureInfo, event: BaseGestureEvent) => {
        // 自定义判定标准
        if (gestureInfo.type == GestureControl.GestureType.LONG_PRESS_GESTURE &&
          gestureInfo.tag == 'longPress1' &&
          event.fingerList.length > 0 &&
          event.fingerList[0].localY < 340) {
          // 返回 CONTINUE 将保持系统判定。
          return GestureJudgeResult.CONTINUE;
        } else {
          return GestureJudgeResult.REJECT;
        }
      })

      // 下半部分
      Stack() {
        Column() {
        }
        .height(340)
        .width('100%')
        .backgroundColor('#F7CE00')
        .opacity(0.1)
        .alignItems(HorizontalAlign.Center)
        .justifyContent(FlexAlign.Center)
        .id('clickColumn')
        .border({
          width: 1,
          color: '#F7BD00',
          radius: { topLeft: 0, topRight: 0, bottomLeft: 24, bottomRight: 24 },
          style: BorderStyle.Dotted
        })

        Text($r('app.string.custom_judge_click'))
          .fontSize(16)
          .fontWeight(400)
          .fontFamily(' HarmonyHeiTi')
          .textAlign(TextAlign.Center)
          .fontColor('#FF9900')
          .opacity(1)
          .id('clickTextPrompt')
      }
      .id('clickArea')
      .gesture(
        TapGesture()
          .tag("tap2")
          .onAction(() => {
            this.message = 'tap';
            ShowToast.longToast($r('app.string.custom_tap_prompt'));
          })
      )
      .gesture(
        LongPressGesture()
          .tag("longPress2")
          .onAction(() => {
            this.message = 'longPress'
          })
      )
      .onGestureJudgeBegin((gestureInfo: GestureInfo, event: BaseGestureEvent) => {
        // 自定义判定标准
        if (gestureInfo.type == GestureControl.GestureType.TAP_GESTURE &&
          gestureInfo.tag == 'tap2' &&
          event.fingerList.length > 0 &&
          event.fingerList[0].localY <= 340) {
          // 返回 CONTINUE 将保持系统判定。
          return GestureJudgeResult.CONTINUE;
        } else {
          return GestureJudgeResult.REJECT;
        }
      })
    }
    .height('100%')
    .width('100%')
    .padding({ left: 12, right: 12 })
    .backgroundColor($r('app.color.background_shallow_grey'))
  }
}
  

sample仓地址:

本功能的sample仓地址:https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部