HarmonyOS 鸿蒙Next中手势识别与交互

HarmonyOS 鸿蒙Next中手势识别与交互 ArkUI 支持哪些手势识别?如何实现点击、长按、滑动、缩放等手势?如何组合多个手势?如何处理手势冲突?如何实现自定义的手势交互效果?(问题来源项目案例整理:https://github.com/heqiyuan35-creator/HydroQuiz.git

3 回复

ArkUI 提供了丰富的手势识别能力。

基础手势

Column() {
  Text('手势测试')
}
// 点击手势
.onClick(() => {
  console.log('单击');
})
// 长按手势
.gesture(
  LongPressGesture({ repeat: false, duration: 500 })
    .onAction(() => {
      console.log('长按');
      this.showContextMenu();
    })
)

滑动手势

@State offsetX: number = 0;
Row() {
  // 内容
}
.translate({ x: this.offsetX })
.gesture(
  PanGesture({ direction: PanDirection.Horizontal })
    .onActionStart(() => {
      this.startX = this.offsetX;
    })
    .onActionUpdate((event: GestureEvent) => {
      this.offsetX = this.startX + event.offsetX;
    })
    .onActionEnd(() => {
      // 判断滑动方向和距离
      if (this.offsetX < -100) {
        this.showDeleteButton();
      } else {
        animateTo({ duration: 200 }, () => {
          this.offsetX = 0;
        });
      }
    })
)

组合手势

// 并行手势 - 同时识别多个手势
.gesture(
  GestureGroup(GestureMode.Parallel,
    TapGesture({ count: 2 })
      .onAction(() => console.log('双击')),
    LongPressGesture()
      .onAction(() => console.log('长按'))
  )
)
// 顺序手势 - 按顺序触发
.gesture(
  GestureGroup(GestureMode.Sequence,
    LongPressGesture({ duration: 300 }),
    PanGesture()
  )
  .onActionEnd(() => console.log('长按后拖动'))
)

缩放手势

@State scale: number = 1;
Image(this.imageUrl)
  .scale({ x: this.scale, y: this.scale })
  .gesture(
    PinchGesture({ fingers: 2 })
      .onActionUpdate((event: GestureEvent) => {
        this.scale = event.scale;
      })
  )

更多关于HarmonyOS 鸿蒙Next中手势识别与交互的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


鸿蒙Next的手势识别基于ArkUI框架,提供统一手势处理接口。支持点击、长按、拖拽、缩放等基础手势,可通过GestureGroup实现多手势组合识别。系统内置手势事件如TapGesture、PinchGesture,开发者可在组件上通过.gesture修饰符绑定。手势响应遵循冒泡机制,支持自定义手势识别器。

在HarmonyOS Next中,ArkUI提供了丰富且强大的手势识别与处理能力,主要通过手势事件(Gesture)和通用事件(Universal Event)来实现。

1. 支持的手势识别与实现方式: ArkUI支持的基础手势包括:

  • 点击(Click/Tap):使用 onClick 事件。
  • 长按(LongPress):使用 onLongPress 事件,可配置最小按压时间。
  • 拖拽(Pan):使用 PanGesture,可识别在指定方向上的滑动。
  • 捏合缩放(Pinch):使用 PinchGesture,识别双指缩放操作。
  • 旋转(Rotation):使用 RotationGesture,识别双指旋转操作。
  • 通用事件:如 onTouch 可获取更原始的触控点信息(按下、移动、抬起)。

这些手势通常通过修饰器(如 .gesture())附加到组件上。例如,为一个 Text 组件添加点击和长按:

Text('点击或长按我')
  .onClick(() => {
    console.log('点击触发');
  })
  .onLongPress(() => {
    console.log('长按触发');
  }, { duration: 1000 })

2. 组合多个手势: 使用 GestureGroup 可以实现手势的组合,主要模式有:

  • 并行识别(ParallelGesture):组内的所有手势可同时被识别和处理,适用于需要同时响应多个手势的场景。
  • 顺序识别(SequenceGesture):组内手势按顺序识别,只有前一个手势成功识别后,才会尝试识别下一个。常用于定义复杂交互序列。
  • 互斥识别(ExclusiveGesture):组内手势互斥,同一时间只有一个手势会被识别(通常是最先匹配的那个)。这是默认的也是最常用的组合方式,用于解决基础冲突。

示例(互斥组合):

Text('组合手势示例')
  .gesture(
    GestureGroup(
      GestureMode.Exclusive,
      PanGesture({ direction: PanDirection.All })
        .onActionStart(() => { console.log('拖拽开始'); }),
      LongPressGesture({ repeat: false })
        .onAction(() => { console.log('长按触发'); })
    )
  )

3. 处理手势冲突: 手势冲突的解决主要依靠以下策略:

  • 使用 GestureGroup 并设置 GestureMode:如上所述,Exclusive(互斥)是处理同一组件上多个手势冲突的常用方法。
  • 设置手势优先级:通过 gestureMask 属性可以控制手势响应的冒泡或拦截行为。例如,.gestureMask(GestureMask.Normal) 允许手势向父组件冒泡,而 .gestureMask(GestureMask.Ignore) 可以阻止子组件的手势影响父组件。
  • 在父组件与子组件之间:合理使用 gestureMask 和事件响应区域(如 hitTestBehavior)来控制事件的传递链。父组件可以通过设置手势并选择 GestureMask.Ignore 来避免被子组件手势干扰,或者通过冒泡机制来接收子组件未处理的手势。

4. 实现自定义手势交互: 对于更复杂或非标准的手势,可以通过监听原始触控事件(onTouch)来实现。onTouch 回调提供了 TouchEvent 对象,其中包含了所有触控点的状态(位置、时间、类型等)。你可以在此基础上自定义识别逻辑:

  • 记录触控点的轨迹。
  • 计算移动距离、速度、角度。
  • 定义特定的移动模式(如画圈、特定形状)并触发相应的回调函数。

示例框架:

@State private touchPoints: Array<TouchPoint> = [];

Text('自定义手势区域')
  .onTouch((event: TouchEvent) => {
    if (event.type === TouchType.Down) {
      // 记录起始点
      this.touchPoints = event.touches;
    } else if (event.type === TouchType.Move) {
      // 计算移动轨迹,实现自定义识别逻辑
      this.handleCustomGesture(event.touches);
    } else if (event.type === TouchType.Up) {
      // 手势结束,处理结果
      this.touchPoints = [];
    }
    // 返回true表示事件已消费,阻止继续冒泡
    return true;
  })

总结: HarmonyOS Next的ArkUI手势系统层次清晰,从基础点击到复杂组合手势均有覆盖。通过 GestureGroupgestureMask 可有效管理手势识别优先级与冲突。对于高度定制化的交互,onTouch 提供了底层触控数据供开发者自由实现识别算法。在实际开发中,建议根据交互复杂度,优先使用系统提供的高级手势,必要时再结合原始触控事件进行扩展。

回到顶部