ArkUI 绑定手势:手势别绑错地方

举报
蓝瘦的蜕变 发表于 2026/10/22 09:27:23 2026/10/22
【摘要】 今天我们先看手势怎么绑到组件上:gesture、priorityGesture、parallelGesture。 这三个名字很像,但它们解决的问题不一样。我们这篇只讲绑定方式,不展开父子组件冲突,不做复杂拖拽排序。 参考文档: https://developer.huawei.com/consumer/cn/doc/h

ArkUI 绑定手势:手势别绑错地方

今天我们先看手势怎么绑到组件上:gesture、priorityGesture、parallelGesture。

这三个名字很像,但它们解决的问题不一样。我们这篇只讲绑定方式,不展开父子组件冲突,不做复杂拖拽排序。

参考文档:

  • https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-interaction-development-guide-overview

gesture 是最普通的绑定

.gesture(
  TapGesture()
    .onAction(() => {
      this.normalText = 'gesture 绑定的 TapGesture 被触发'
    })
)

gesture 适合一个组件自己识别一个手势。比如点一张卡片、点一个图片区域、点一个自定义控件。

priorityGesture 先拿识别机会

.priorityGesture(
  TapGesture()
    .onAction(() => {
      this.priorityText = 'priorityGesture 绑定的 TapGesture 被触发'
    })
)

它适合你明确希望当前组件的手势更早参与识别的场景。真实项目里常见于父子组件都有手势的时候,不过那部分我们放到手势冲突篇再展开。

parallelGesture 允许并行识别

.parallelGesture(
  TapGesture()
    .onAction(() => {
      this.parallelText = 'parallelGesture 里的 TapGesture 被触发'
    })
)

并行手势适合“不想独占”的动作。比如组件内部已有点击逻辑,同时你还希望外层也能监听某个手势。

如果你写手势时发现“点了没反应”或者“外层抢了内层动作”,大概率就不是手势本身难,而是绑定位置和优先级没分清。

完整示例代码

文件位置:entry/src/main/ets/pages/arkUI/interaction/ArkUIGestureBindingDemo.ets

@Entry
@Component
struct ArkUIGestureBindingDemo {
  @State normalText: string = '普通绑定还没触发'
  @State priorityText: string = '优先手势还没触发'
  @State parallelText: string = '并行手势还没触发'

  private showTip(message: string): void {
    this.getUIContext().getPromptAction().showToast({
      message: message,
      duration: 1200,
      bottom: 120
    })
  }

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  gestureCard(title: string, desc: string, color: string) {
    Column({ space: 10 }) {
      Text(title)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor(color)
      Text(desc)
        .fontSize(13)
        .fontColor('#4B5563')
        .lineHeight(20)
    }
    .width('100%')
    .padding(16)
    .borderRadius(14)
    .backgroundColor('#FFFFFF')
    .border({ width: 1, color: '#E5E7EB' })
    .alignItems(HorizontalAlign.Start)
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI 绑定手势')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('手势别绑错地方')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('手势不是只能写一个。普通绑定、优先绑定、并行绑定解决的是不同关系。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('gesture:最普通的绑定方式', '组件自己识别这个手势,适合简单独立的触发区。')
        Column() {
          this.gestureCard('普通点击手势', '点这张卡片,TapGesture 会更新下面的结果。', '#2563EB')
          Text(this.normalText)
            .fontSize(13)
            .fontColor('#111827')
            .lineHeight(20)
            .padding(12)
            .borderRadius(10)
            .backgroundColor('#F8FAFC')
            .width('100%')
        }
        .width('100%')
        .gesture(
          TapGesture()
            .onAction(() => {
              this.normalText = 'gesture 绑定的 TapGesture 被触发'
              this.showTip('gesture 手势触发')
            })
        )

        this.sectionTitle('priorityGesture:先把这个手势放到前面判断', '当外层和内层都有手势时,优先级会影响谁先拿到机会。')
        Column() {
          this.gestureCard('优先点击手势', '这里先展示绑定写法,不展开复杂父子冲突。', '#0F766E')
          Text(this.priorityText)
            .fontSize(13)
            .fontColor('#111827')
            .lineHeight(20)
            .padding(12)
            .borderRadius(10)
            .backgroundColor('#F8FAFC')
            .width('100%')
        }
        .width('100%')
        .priorityGesture(
          TapGesture()
            .onAction(() => {
              this.priorityText = 'priorityGesture 绑定的 TapGesture 被触发'
              this.showTip('priorityGesture 手势触发')
            })
        )

        this.sectionTitle('parallelGesture:允许和内部手势一起识别', '如果希望两个手势都能参与,可以先从并行绑定理解。')
        Column() {
          this.gestureCard('并行点击手势', '点击卡片时,onClick 和 parallelGesture 都可能参与响应。', '#C2410C')
          Text(this.parallelText)
            .fontSize(13)
            .fontColor('#111827')
            .lineHeight(20)
            .padding(12)
            .borderRadius(10)
            .backgroundColor('#F8FAFC')
            .width('100%')
        }
        .width('100%')
        .onClick(() => {
          this.parallelText = 'onClick 先记录了一次普通点击'
          this.showTip('onClick 已响应')
        })
        .parallelGesture(
          TapGesture()
            .onAction(() => {
              this.parallelText = 'parallelGesture 里的 TapGesture 被触发'
              this.showTip('parallelGesture 手势触发')
            })
        )
      }
      .width('100%')
      .padding(24)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F8FAFC')
  }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。