HarmonyOS鸿蒙Next中快滑手势怎么判断滑动的方向?是上下左右的哪个?

HarmonyOS鸿蒙Next中快滑手势怎么判断滑动的方向?是上下左右的哪个? SwipeGesture 用于触发快滑手势,滑动速度需大于速度阈值,默认最小速度为100vp/s。

应该怎么判断滑动的方向?

9 回复

核心接口:SwipeGestureEvent.angle

表示快滑手势的角度,即两根手指间的线段与水平方向的夹角变化的度数,单位为deg。

说明:

角度计算方式:当快滑手势被识别后,连接两根手指之间的线被识别为起始线条。随着手指的滑动,手指之间的线条会发生旋转。根据起始线条和当前线条两端点的坐标,使用反正切函数分别计算其相对于水平方向的夹角。

最终的旋转角度为:arctan2(cy2-cy1, cx2-cx1) - arctan2(y2-y1, x2-x1)

在起始线条为坐标系的情况下,顺时针旋转为0到180度,逆时针旋转为-180到0度。

示例代码:

@Entry
@ComponentV2
struct SwipeGestureExample {
  @Local directionText: string = "无"

  build() {
    Column() {
      Text(this.directionText).fontSize(50)
    }
    .gesture(SwipeGesture()
      .onAction((event: SwipeGestureEvent) => {
        const angle = event.angle
        if (angle > -45 && angle < 45) {
          this.directionText = "右"
        } else if (angle < -135 || angle > 135) {
          this.directionText = "左"
        } else if (angle > 45 && angle < 135) {
          this.directionText = "下"
        } else if (angle > -135 && angle < -45) {
          this.directionText = "上"
        }
      }))
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

效果图:

效果图

更多关于HarmonyOS鸿蒙Next中快滑手势怎么判断滑动的方向?是上下左右的哪个?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙开发中,通过SwipeGesture判断滑动方向时,可以通过GestureEvent对象的滑动角度速度向量属性实现。以下是具体方法和实现示例:


一、通过角度(angle)判断

GestureEvent中的angle属性表示滑动方向与X轴顺时针方向的夹角(单位:度),取值范围为[0,180](-180,0)。具体方向对应关系如下:

  • 右滑:角度接近0°(范围:-45°~45°)
  • 左滑:角度接近180°或-180°(范围:135°~180° 或 -180°~-135°)
  • 下滑:角度接近90°(范围:45°~135°)
  • 上滑:角度接近-90°(范围:-135°~-45°)

示例代码

.gesture(
  SwipeGesture({ direction: SwipeDirection.All })
    .onAction((event: GestureEvent) => {
      if (event.angle >= -45 && event.angle <= 45) {
        console.info("右滑");
      } else if (event.angle >= 135 || event.angle <= -135) {
        console.info("左滑");
      } else if (event.angle > 45 && event.angle < 135) {
        console.info("下滑");
      } else if (event.angle < -45 && event.angle > -135) {
        console.info("上滑");
      }
    })
)

二、通过速度向量(velocityX/velocityY)判断

若需要更精确判断水平或垂直滑动,可通过velocityXvelocityY的速度分量(单位:vp/s):

  • 水平方向velocityX的正负值分别表示右滑(正)和左滑(负)。
  • 垂直方向velocityY的正负值分别表示下滑(正)和上滑(负)。

代码片段

if (Math.abs(event.velocityX) > Math.abs(event.velocityY)) {
  // 水平滑动为主
  if (event.velocityX > 0) {
    console.info("右滑");
  } else {
    console.info("左滑");
  }
} else {
  // 垂直滑动为主
  if (event.velocityY > 0) {
    console.info("下滑");
  } else {
    console.info("上滑");
  }
}

三、注意事项

  1. 速度阈值:需确保滑动速度超过默认的100vp/s(或自定义的阈值)才能触发SwipeGesture1。
  2. 方向过滤:若仅需监听特定方向,可在SwipeGesture初始化时通过direction参数限制(如SwipeDirection.Horizontal)。
  3. 多指操作:若设置fingers参数为多指,需确保触点数量符合条件才会触发回调。

完整示例场景

// 监听多方向快滑手势并打印结果
@Entry
@Component
struct SwipeExample {
  build() {
    Column() {
      Text("快滑区域")
        .width(300)
        .height(200)
        .border({ width: 2 })
        .gesture(
          SwipeGesture({ direction: SwipeDirection.All })
            .onAction((event: GestureEvent) => {
              let direction = "";
              if (event.angle >= -45 && event.angle <= 45) direction = "右滑";
              else if (event.angle >= 135 || event.angle <= -135) direction = "左滑";
              else if (event.angle > 45 && event.angle < 135) direction = "下滑";
              else direction = "上滑";
              console.info(`滑动方向:${direction},速度:${event.speed}vp/s`);
            })
        )
    }
  }
}

通过上述方法,可准确识别用户滑动方向并实现交互逻辑。

信息来源

SwipeGesture

在SwipeGesture属性的onAction回调中的GestureEvent参数里,有offsetx和offsety,是手势事件相对于手指按下时在不同坐标轴的偏移量,可用于判断滑动方向

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,

offsetx和offsety是PanGesture手势才会触发的。
SwipeGesture要用SwipeGestureEvent。
https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-gesture-common#swipegestureevent11对象说明

噢噢,刚看到大佬的回答是在手机端,在智慧屏端使用灵犀指向是可以正常使用SwipeGesture中的offsetx和offsety,

如果能直接拿到 PanGesture 手势触发的返回值,有更简单的:velocityX 和 velocityY。 可以获取当前手势的x轴方向速度和y轴方向速度。 可以参考 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-gesture-common#pangestureevent11%E5%AF%B9%E8%B1%A1%E8%AF%B4%E6%98%8E

在HarmonyOS Next中,通过PanGestureoffsetXoffsetY属性判断滑动方向。比较两者绝对值:若offsetX绝对值大于offsetY,则为左右滑动(offsetX > 0为右,反之为左);反之则为上下滑动(offsetY > 0为下,反之为上)。

在HarmonyOS Next中,使用SwipeGesture监听快滑手势时,其回调事件onAction的参数event(类型为GestureEvent)提供了直接获取滑动方向的方法。

核心方法是:event.offsetXevent.offsetY

这两个属性分别代表了从手势触碰到离开,在X轴和Y轴上滑动的总偏移量。通过判断这两个值的正负和大小,即可精确判断滑动方向。

判断逻辑如下:

  1. 获取偏移量:在onAction(event: GestureEvent) => void回调中,读取event.offsetXevent.offsetY
  2. 设定方向阈值:为避免轻微抖动被误判,可设定一个最小滑动距离阈值(例如5vp)。
  3. 判断主方向:比较offsetXoffsetY的绝对值,绝对值更大的轴即为主滑动方向。
  4. 确定具体方向
    • offsetX的绝对值更大且offsetX > 0,则为向右滑动。
    • offsetX的绝对值更大且offsetX < 0,则为向左滑动。
    • offsetY的绝对值更大且offsetY > 0,则为向下滑动。
    • offsetY的绝对值更大且offsetY < 0,则为向上滑动。

示例代码片段:

@Entry
@Component
struct SwipeGestureExample {
  @State direction: string = '未滑动'

  build() {
    Column() {
      Text(this.direction)
        .fontSize(30)
        .margin(50)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    // 应用快滑手势识别
    .gesture(
      SwipeGesture({ speed: 100 })
        .onAction((event: GestureEvent) => {
          const minDistance = 5; // 设定阈值,单位vp
          let dx = event.offsetX;
          let dy = event.offsetY;

          // 判断滑动距离是否超过阈值
          if (Math.abs(dx) < minDistance && Math.abs(dy) < minDistance) {
            return; // 滑动距离过小,不处理
          }

          // 判断主方向
          if (Math.abs(dx) > Math.abs(dy)) {
            // 水平方向为主
            this.direction = dx > 0 ? '向右快滑' : '向左快滑';
          } else {
            // 垂直方向为主
            this.direction = dy > 0 ? '向下快滑' : '向上快滑';
          }
        })
    )
  }
}

简要说明:

  • event.offsetX/Y是系统计算好的累积偏移量,直接使用即可,无需手动计算起点和终点。
  • 通过比较两轴偏移量的绝对值,可以确保识别出用户意图中的主要滑动方向,避免斜向滑动产生歧义。
  • 增加一个minDistance阈值是常见的最佳实践,可以提高交互的准确性。

因此,你不需要自行计算轨迹,直接利用GestureEvent对象中的偏移量属性进行判断即可。

回到顶部