事件传递
- HitTestMode
- hitTestBehavior
- onChildTouchTest
- onTouchIntercept
手势
| 名称 | 描述 |
|---|---|
| TapGesture | 点击手势,支持单次点击、多次点击识别。 |
| LongPressGesture | 长按手势。 |
| PanGesture | 平移手势,滑动最小距离为5vp时识别成功。 |
| PinchGesture | 捏合手势。 |
| RotationGesture | 旋转手势。 |
| SwipeGesture | 滑动手势,滑动最小速度为100vp/s时识别成功。 |
| GestureGroup | 手势识别组,多种手势组合为复合手势,支持连续识别、并行识别和互斥识 |
GestureEvent对象说明
| 类型 | 描述 | |
|---|---|---|
| repeat | boolean | 是否为重复触发事件,用于LongPressGesture手势触发场景。 |
| offsetX | number | 手势事件偏移量X,单位为vp,用于PanGesture手势触发场景,从左向右滑动offsetX为正,反之为负。 |
| offsetY | number | 手势事件偏移量Y,单位为vp,用于PanGesture手势触发场景,从上向下滑动offsetY为正,反之为负。 |
| angle | number | 用于RotationGesture手势触发场景时,表示旋转角度。用于SwipeGesture手势触发场景时,表示滑动手势的角度,即两根手指间的线段与水平方向的夹角变化的度数。**说明:**角度计算方式:滑动手势被识别到后,连接两根手指之间的线被识别为起始线条,随着手指的滑动,手指之间的线条会发生旋转,根据起始线条两端点和当前线条两端点的坐标,使用反正切函数分别计算其相对于水平方向的夹角,最后arctan2(cy2-cy1,cx2-cx1)-arctan2(y2-y1,x2-x1)为旋转的角度。以起始线条为坐标系,顺时针旋转为0到180度,逆时针旋转为-180到0度。 |
| scale | number | 缩放比例,用于PinchGesture手势触发场景。 |
| pinchCenterX | number | 捏合手势中心点的x轴坐标,单位为vp,用于PinchGesture手势触发场景。 |
| pinchCenterY | number | 捏合手势中心点的y轴坐标,单位为vp,用于PinchGesture手势触发场景。 |
| speed8+ | number | 滑动手势速度,即所有手指相对当前组件元素原始区域滑动的平均速度,单位为vp/秒,用于SwipeGesture手势触发场景。 |
| fingerList8+ | FingerInfo[] | 输入源为触屏产生的手势,fingerList中会包含触发事件的所有触点信息;由鼠标发起的手势,fingerList中只会有一条记录;触摸板的事件大类与鼠标一致,所以由触摸板发起的手势,fingerList只会携带一条记录。**说明:**手指索引编号与位置对应,即fingerList[index]的id为index。先按下且未参与当前手势触发的手指在fingerList中对应位置为空。 |
| timestamp8+ | number | 事件时间戳。**说明:**单位:ns |
| target8+ | EventTarget | 触发手势事件的元素对象显示区域。 |
| source8+ | SourceType | 事件输入设备。 |
| pressure9+ | number | 按压的压力大小。 |
| tiltX9+ | number | 手写笔在设备平面上的投影与设备平面X轴的夹角。 |
| tiltY9+ | number | 手写笔在设备平面上的投影与设备平面Y轴的夹角。 |
| sourceTool9+ | SourceTool | 事件输入源。 |
| velocityX10+ | number | 用于PanGesture手势中,获取当前手势的x轴方向速度。坐标轴原点为屏幕左上角,分正负方向速度,从左往右为正,反之为负。单位为vp/s。 |
| velocityY10+ | number | 用于PanGesture手势中,获取当前手势的y轴方向速度。坐标轴原点为屏幕左上角,分正负方向速度,从上往下为正,反之为负。单位为vp/s。 |
| velocity10+ | number | 用于PanGesture手势中,获取当前手势的主方向速度。为xy轴方向速度的平方和的算术平方根。单位为vp/s。 |
TapGesture
参数
- count?: number; 表示相比上次300ms再次点击,总共点击了几次才响应这里的事件
- fingers?: number 几根手指头
属性
- onAction 触发的回调
- tag 设置Tap手势标志,用于自定义手势判定时区分绑定的手势。
// 单指双击文本触发手势事件
Text('Click twice').fontSize(28)
.gesture(
TapGesture({ count: 2 })
.onAction((event: GestureEvent) => {
console.log('点击了两次')
})
)
// 如果设置了 onClick 则不会触发 TapGesture
.onClick(()=>{
this.color = Color.Red
})
LongPressGesture 长按
参数
- duration: 500 长按几秒
- fingers: 1 几个手指头
- repeat: false 是否重复,肯定不重复呀
属性
- onAction 触发的任务
- onActionEnd 长按动作一结束触发,手指头抬起来的时候
Text('LongPress onAction:' + this.count).fontSize(28)// 单指长按文本触发该手势事件
.gesture(
LongPressGesture({
duration: 500,// 长按几毫秒触发 默认500
fingers: 1, // 几个手指头,默认1个
// repeat: true // 是否重复,一半也不会重复
})// 由于repeat设置为true,长按动作存在时会连续触发,触发间隔为duration(默认值500ms)
.onAction((event: GestureEvent) => {
// if (event && event.repeat) {
this.count++
// }
})// 长按动作一结束触发
.onActionEnd((event: GestureEvent) => {
this.count = 0
})
)
PanGesture 拖拽
offsetX 和 offsetY 每次移动都从新0开始,记得累加哈 参数
- fingers?: number; 手指个数 默认是1
- direction?: PanDirection;用于指定设置滑动方向,此枚举值支持逻辑与(&)和逻辑或(|)运算。默认值:PanDirection.All,比如只有水平方向可以,垂直方向可以,left ,right top ,bottom
- distance?: number;用于指定触发拖动手势事件的最小拖动距离,单位为vp。默认值:5
属性
- onActionStart
- onActionUpdate
- onActionEnd
- onActionCancel
@State offsetX: number = 0
@State offsetY: number = 0
@State positionX: number = 0
@State positionY: number = 0
// private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Left | PanDirection.Right })
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All })
build() {
Column() {
Column() {
Text('PanGesture offset:\nX: ' + this.offsetX + '\n' + 'Y: ' + this.offsetY)
}
.height(200)
.width(300)
.padding(20)
.border({ width: 3 })
.margin(50)
.translate({ x: this.offsetX, y: this.offsetY, z: 0 }) // 以组件左上角为坐标原点进行移动
// 左右拖动触发该手势事件
.gesture(
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start')
})
.onActionUpdate((event: GestureEvent) => {
if (event) {
this.offsetX = this.positionX + event.offsetX
this.offsetY = this.positionY + event.offsetY
}
})
.onActionEnd((event: GestureEvent) => {
this.positionX = this.offsetX
this.positionY = this.offsetY
console.info('Pan end')
})
.onActionCancel(() => {
console.info('Pan onActionCancel')
})
)
PinchGesture 用于触发捏合手势,放大,触发捏合手势的最少手指为2指,比如PhotoView的实现
event.scale 每次都是从新1开始,记得累加哈
参数
- fingers: 2 手指个数,默认是2个
- distance 距离
属性
- onActionStart
- onActionUpdate
- onActionEnd
- onActionCancel
@Entry
@Component
struct PinchGestureExample {
@State scaleValue: number = 1
@State pinchValue: number = 1
@State pinchX: number = 0
@State pinchY: number = 0
build() {
Column() {
Stack() {
Image($r('app.media.img')).width('100%').height('100%').scale({ x: this.scaleValue, y: this.scaleValue, z: 0 })
Column() {
Text('PinchGesture scale:\n' + this.scaleValue)
Text('PinchGesture center:\n(' + this.pinchX + ',' + this.pinchY + ')')
}
.height(200)
.width(300)
.padding(20)
.border({ width: 3 })
.margin({ top: 100 })
// 三指捏合触发该手势事件
.gesture(
PinchGesture({ fingers: 2 })
.onActionStart((event: GestureEvent) => {
console.info('Pinch start')
})
.onActionUpdate((event: GestureEvent) => {
if (event) {
this.scaleValue = this.pinchValue * event.scale
this.pinchX = event.pinchCenterX
this.pinchY = event.pinchCenterY
console.log("event.scale=>" + event.scale)
}
})
.onActionEnd((event: GestureEvent) => {
this.pinchValue = this.scaleValue
console.info('Pinch end')
})
)
}
}.width('100%')
.height('100%')
}
}
RotationGesture
用于触发旋转手势事件,触发旋转手势的最少手指为2指, GestureEvent.angle拿到旋转度数
SwipeGesture 大距离滑动的时候,估计也用不上
GestureGroup
- mode: GestureMode, GestureMode.Sequence 默认是顺讯识别,只有一个响应 ,Parallel 并发识别 互不影响,Exclusive互斥识别
- ...gesture: GestureType[] 上面的几个手势
下面是类似photoview,同时识别 移动和缩放
@Entry
@Component
struct PinchGestureExample {
@State scaleValue: number = 1
@State pinchValue: number = 1
@State pinchX: number = 0
@State pinchY: number = 0
@State offsetX: number = 0
@State offsetY: number = 0
@State positionX: number = 0
@State positionY: number = 0
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All })
build() {
Column() {
Stack() {
Image($r('app.media.img'))
.width('100%')
.interpolation(ImageInterpolation.High)
.height('100%')
.scale({ x: this.scaleValue, y: this.scaleValue, z: 0 })
.translate({ x: this.offsetX, y: this.offsetY })
Column() {
Text('PinchGesture scale:\n' + this.scaleValue)
Text('PinchGesture center:\n(' + this.pinchX + ',' + this.pinchY + ')')
}
.height(200)
.width(300)
.padding(20)
.border({ width: 3 })
.margin({ top: 100 })
// 三指捏合触发该手势事件
}.gesture(GestureGroup(GestureMode.Parallel,
PinchGesture({ fingers: 2 })
.onActionStart((event: GestureEvent) => {
console.info('Pinch start')
})
.onActionUpdate((event: GestureEvent) => {
if (event) {
this.scaleValue = this.pinchValue * event.scale
this.pinchX = event.pinchCenterX
this.pinchY = event.pinchCenterY
console.log("event.scale=>" + event.scale)
}
})
.onActionEnd((event: GestureEvent) => {
this.pinchValue = this.scaleValue
console.info('Pinch end')
}),
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start')
})
.onActionUpdate((event: GestureEvent) => {
if (event) {
this.offsetX = this.positionX + event.offsetX
this.offsetY = this.positionY + event.offsetY
}
})
.onActionEnd((event: GestureEvent) => {
this.positionX = this.offsetX
this.positionY = this.offsetY
console.info('Pan end')
})
))
}.width('100%')
.height('100%')
}
}