#我的鸿蒙开发手记# HarmonyOS开发中的:手势使用详情 原创

陈花花花
发布于 2025-5-5 22:37
浏览
1收藏

前言

随着现在移动设备和智能设备的普及,用户对交互体验的要求越来越高,而手势操作作为一种直观、自然的交互方式,已经成为现代应用开发中不可或缺的一部分。HarmonyOS作为面向万物互联时代的操作系统,提供了强大的手势识别功能,支持开发者通过简单的代码实现丰富多样的手势操作,从而提升应用的用户体验和交互效率。单一手势操作是HarmonyOS手势系统的基础,它通过简单的触摸动作(如点击、滑动、拖拽等)实现特定的功能,为用户提供便捷的操作方式。那么本文就来详细介绍HarmonyOS中单一手势操作的类型、实现方法以及设计原则,并结合实际案例展示其在不同场景中的应用,帮助大家更好地理解和使用HarmonyOS的手势功能。

什么是单一手势?

在HarmonyOS开发中,通用事件按照触发类型来分类,包括触屏事件、键鼠事件、焦点事件和拖拽事件。而手势事件由绑定手势方法和绑定的手势组成,绑定的手势可以分为单一手势和组合手势两种类型,根据手势的复杂程度进行区分。但是单一手势,是手势的基本单元,是所有复杂手势的组成部分。

手势操作的类型及实现

关于单一手势操作的类型有点击、长按、拖动、捏合、旋转、滑动六大类型,具体实现如下所示。

1、点击手势(TapGesture)

点击手势是最基本的手势操作,支持单次点击和多次点击。通过TapGesture可以轻松实现按钮点击、菜单打开等功能,以下代码展示了如何实现一个双击操作:

@Entry
@Component
struct Index {
  @State value: string = "";

  build() {
    Column() {
      Text('双击').fontSize(28)
        .gesture(
          TapGesture({ count: 2 }) // 绑定双击事件,绑定count为2的TapGesture
            .onAction((event: GestureEvent|undefined) => {
              this.value = JSON.stringify(event.fingerList[0]);
            }))
      Text(this.value)
    }
    .height(200)
    .width(250)
    .padding(20)
    .border({ width: 3 })
    .margin(30)
  }
}

2、长按手势(LongPressGesture)

长按手势用于触发长按手势事件,通过LongPressGesture可以轻松实现长按复制等功能,以下代码展示了如何实现在Text组件上绑定可以重复触发的长按手势:

@Entry
@Component
struct Index {
  @State count: number = 0;

  build() {
    Column() {
      Text('长按').fontSize(28)
        .gesture(
          // 绑定可以重复触发的LongPressGesture
          LongPressGesture({ repeat: true })
           .onAction((event: GestureEvent|undefined) => {
              if(event){
                if (event.repeat) {
                  this.count++;
                }
              }
            })
            .onActionEnd(() => {
              this.count = 0;
            })
        )
    }
    .height(200)
    .width(250)
    .padding(20)
    .border({ width: 3 })
    .margin(30)
  }
}

3、拖动手势(PanGesture)

拖动手势用于触发拖动手势事件,滑动达到最小滑动距离(默认值为5vp)时拖动手势识别成功,以下代码展示了在Text组件上绑定拖动手势为例,可以通过在拖动手势的回调函数中修改组件的布局位置信息来实现组件的拖动:

@Entry
@Component
struct Index {
  @State offsetX: number = 0;
  @State offsetY: number = 0;
  @State positionX: number = 0;
  @State positionY: number = 0;

  build() {
    Column() {
      Text('拖动')
        .fontSize(28)
        .height(200)
        .width(300)
        .padding(20)
        .border({ width: 3 })
          // 在组件上绑定布局位置信息
        .translate({ x: this.offsetX, y: this.offsetY, z: 0 })
        .gesture(
          // 绑定拖动手势
          PanGesture()
           .onActionStart((event: GestureEvent|undefined) => {
            })
              // 当触发拖动手势时,根据回调函数修改组件的布局位置信息
            .onActionUpdate((event: GestureEvent|undefined) => {
              if(event){
                this.offsetX = this.positionX + event.offsetX;
                this.offsetY = this.positionY + event.offsetY;
              }
            })
            .onActionEnd(() => {
              this.positionX = this.offsetX;
              this.positionY = this.offsetY;
            })
        )
    }
    .height(200)
    .width(250)
  }
}

4、捏合手势(PinchGesture)

捏合手势用于触发捏合手势事件,常用于图片和地图的缩放操作,这里举例以在Column组件上绑定三指捏合手势为例,可以通过在捏合手势的函数回调中获取缩放比例,实现对组件的缩小或放大:

@Entry
@Component
struct Index {
  @State scaleValue: number = 1;
  @State pinchValue: number = 1;
  @State pinchX: number = 0;
  @State pinchY: number = 0;

  build() {
    Column() {
      Column() {
        Text('捏合')
      }
      .height(200)
      .width(300)
      .border({ width: 3 })
      .margin({ top: 100 })
      // 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大
      .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 })
      .gesture(
        // 在组件上绑定三指触发的捏合手势
        PinchGesture({ fingers: 3 })
          .onActionStart((event: GestureEvent|undefined) => {
          })
            // 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例
          .onActionUpdate((event: GestureEvent|undefined) => {
            if(event){
              this.scaleValue = this.pinchValue * event.scale;
              this.pinchX = event.pinchCenterX;
              this.pinchY = event.pinchCenterY;
            }
          })
          .onActionEnd(() => {
            this.pinchValue = this.scaleValue;
          })
      )
    }
  }
}

5、旋转手势(RotationGesture)

旋转手势用于触发旋转手势事件,这里以在Text组件上绑定旋转手势实现组件的旋转为例,可以通过在旋转手势的回调函数中获取旋转角度,从而实现组件的旋转:

@Entry
@Component
struct Index {
  @State angle: number = 0;
  @State rotateValue: number = 0;

  build() {
    Column() {
      Text('旋转').fontSize(28)
        // 在组件上绑定旋转布局,可以通过修改旋转角度来实现组件的旋转
        .rotate({ angle: this.angle })
        .gesture(
          RotationGesture()
           .onActionStart((event: GestureEvent|undefined) => {
            })
              // 当旋转手势生效时,通过旋转手势的回调函数获取旋转角度,从而修改组件的旋转角度
            .onActionUpdate((event: GestureEvent|undefined) => {
              if(event){
                this.angle = this.rotateValue + event.angle;
              }
            })
              // 当旋转结束抬手时,固定组件在旋转结束时的角度
            .onActionEnd(() => {
              this.rotateValue = this.angle;
            })
            .onActionCancel(() => {
            })
        )
        .height(200)
        .width(300)
        .padding(20)
        .border({ width: 3 })
        .margin(100)
    }
  }
}

6、滑动手势(SwipeGesture)

滑动手势用于触发滑动事件,当滑动速度大于100vp/s时可以识别成功,可以实现上下左右滑动操作,常用于列表滚动和页面切换,以在Column组件上绑定滑动手势实现组件的旋转为例:

@Entry
@Component
struct Index {
  @State rotateAngle: number = 0;
  @State speed: number = 1;

  build() {
    Column() {
      Column() {
        Text('滑动')
      }
      .border({ width: 3 })
      .width(300)
      .height(200)
      .margin(100)
      // 在Column组件上绑定旋转,通过滑动手势的滑动速度和角度修改旋转的角度
      .rotate({ angle: this.rotateAngle })
      .gesture(
        // 绑定滑动手势且限制仅在竖直方向滑动时触发
        SwipeGesture({ direction: SwipeDirection.Vertical })
          // 当滑动手势触发时,获取滑动的速度和角度,实现对组件的布局参数的修改
          .onAction((event: GestureEvent|undefined) => {
            if(event){
              this.speed = event.speed;
              this.rotateAngle = event.angle;
            }
          })
      )
    }
  }
}

手势操作的设计原则

关于手势操作的设计原则方面,分为两个方面:自然直观和一致性。

1、自然直观

手势设计应模拟现实世界中的操作习惯,让用户能够凭借直觉进行交互,比如从屏幕底部边缘向上滑动返回主屏幕,这一操作类似于翻开书页的动作。

2、一致性

在整个HarmonyOS生态系统中,手势操作的含义和效果应保持一致,比如双指缩放手势在不同应用中都应实现放大或缩小的功能。

实际应用案例

这里举两个简单的实用示例,方便各位学习使用。

1、音乐播放器应用

在音乐播放器应用中,用户可以通过左右滑动切换歌曲,双指缩放调整封面大小,以下代码展示了如何实现左右滑动切换歌曲:

@Entry
@Component
struct MusicPlayerSwipe {
  @State currentSongIndex: number = 0;
  @State songs: string[] = ['Song 1', 'Song 2', 'Song 3'];

  build() {
    Column() {
      Text(this.songs[this.currentSongIndex])
    }
    .swipe({
      start: SwipeDirection.Left,
      onSwipe: () => {
        if (this.currentSongIndex < this.songs.length - 1) {
          this.currentSongIndex++;
        }
      }
    })
    .swipe({
      start: SwipeDirection.Right,
      onSwipe: () => {
        if (this.currentSongIndex > 0) {
          this.currentSongIndex--;
        }
      }
    })
  }
}

2、手势截屏

手势截屏是另一个实用的功能,用户可以通过下滑手势调用全屏截图功能,通过双击手势调用区域截图功能,以下代码展示了如何实现全屏截图:

Stack() {
  Column() {
    ...
  }
  .gesture(
    PanGesture({
      fingers: 1,
      direction: PanDirection.Down,
      distance: CommonConstants.MINIMUM_FINGER_DISTANCE
    })
      .onActionStart(() => {
        let screenshotOptions: screenshot.ScreenshotOptions = {
          rotation: 0
        };
        screenshot.save(screenshotOptions, (err: Error, data: image.PixelMap) => {
          if (err) {
            Logger.error(`Failed to save the screenshot. Error:${JSON.stringify(err)}`);
          }
          if (this.pixelMap !== undefined) {
            this.pixelMap.release();
          }
          this.pixelMap = data;
          this.dialogController.open();
        });
      })
  )
}

结束语

通过本文的介绍,想必大家都了解到HarmonyOS提供强大的手势识别系统,支持多种单一手势操作。这些手势操作不仅可以通过简单的代码实现,还能通过合理的设计原则提升用户体验。在实际应用中,手势操作可用于音乐播放器、截屏工具等多种场景,为用户带来便捷高效的交互体验。作为HarmonyOS开发者,掌握单一手势操作的实现和优化是开发高效、易用应用的关键。希望本文的内容能够帮助各位开发者更好地理解和使用HarmonyOS的手势功能,从而在万物互联的时代中,为用户提供更加自然、便捷的交互体验。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
1
收藏 1
回复
举报
回复
    相关推荐