HarmonyOS手势处理
手势处理
手势事件
- 通过不同组件绑定不同手势,设置手势事件响应方式,当手势识别成功,Ark通过事件回调通知手势识别结果
绑定手势的方法
. gesture
- 常规手势绑定方法
.gesture(gestureType,mak?:GestureMask)
. priorityGesture
- 带优先级的绑定方法
.priorityGesture(gestureType,mask?:GestureMask)
- 带优先级的绑定方法,在组件上绑定优先识别手势
- 在默认情况下,当父子组件同时使用gesture,子组件优先识别通过gesture绑定手势
- 当父组件使用priorityGesture绑定与子组件相同手势时,父组件优先通过手势判定
- 例外:长按手势,长按手势是根据长时间的长短决定优先级
.parallelGesture
- 并行手势绑定方法
.parallelGesture(gestureType,mask?:GestureMask)
- 可以在父组件和子组件上同时响应相同的手势
- 在默认情况下,手势事件不是冒泡事件
- 当父子组件绑定相同手势时,就会出现手势竞争,最多只能有一个组件的手势能获得响应
- 当父组件绑定了并行手势parallelGesture时,父子组件可以同时触发,实现类似冒泡的效果
按照手势数量分
单一手势
点击手势(TapGesture)
- 点击手势支持单次点击和多次点击
- **count:**声明该点击手势识别次数。默认为1
- **fingers:**用于触发点击的手指数量,最小值1,最大值10,当配置多指时,如果第一根手指按下300ms以内没有足够的手指按下,则视为无效
- **事件:**onAction( event ) 手势识别成功回调
长按手势(LongPressGesture)
- 长按手势用于触发长按事件,有三个可选参数
- **fingers:**用于声明手势的所需要最少手指数量,最小为1,最大为10,默认1
- **repeat:**用于声明是否连续触发回调事件(设置为true,长按连续触发)
- **duration:**用于声明触发长按所需的最短时间,单位ms,默认500
- 事件:
- onAction( event ):手势识别成功的回调
- onActionEnd( event ):手势识别成功,当最后一根手指抬起后触发回调
- onActionCancel( event ):手势识别成功,接收到触摸取消事件触发回调
拖动手势(PanGesture)
- 拖动手势用于触发拖动事件,滑动达到最小距离时拖动,手势识别成功有三个参数
- fingers:手指数量,最小为2,最大为5,默认2
- direction:声明拖动的手势方向,此枚举值(PanDirection)支持逻辑与和逻辑或运算,默认值ALL
- distance:用于申明触发拖动的最小识别距离,单位vp,默认5
- 事件
- onActionStart(()=>{}) 手势识别成功回调
- onActionUpdate(()=>{}) 手势移动过程中的回调
- onActionEnd(()=>{}) 手势识别成功,手指抬起触发回调
- onActionCancel() 手势识别成功,接收到触摸取消时间触发
捏合手势(PinchGesture)
-
有两个可选参数
- fingers:手指数量
- distance:触发捏合手势的最小距离,默认值为5
-
事件
- onActionStart(()=>{ }) 手势识别成功的回调
- onActionUpdate(()=>{ }) 手势移动过程中的回调
- onActionEnd(()=>{ }) 手势识别成功,手指抬起时触发
- onActioncancel( ) 手势识别成功,接收到触摸取消事件触发
-
代码
-
Text('这是一个捏合手势') .width(200) .height(300) .border({ width:3 }) .margin({ top:100 }) //scale 缩放 .scale({ x:this._offset, y:this._offset }) .gesture( PinchGesture() .onActionStart(() => { console.log(`>>>捏合手势开始触发`) }) .onActionUpdate((event) => { //调整缩放比例 //event.scale 这是比例值 大于0 console.log(`>>>>${event.scale}`) this._offset = this._offset * event.scale if(this._offset <= 0.5){ this._offset= 0.5 } }) .onActionEnd(() => { console.log(`>>>>捏合手势结束`) }) )
-
旋转手势(RotationGesture)
-
有两个可选参数
- fingers:用于声明触发旋转手势需要最少手指数量为2,最大为5,默认为2
- angle:选择手势最小改变度数,单位deg
-
事件
- onActionStart( ):手势识别成功的回调
- onActionUpdate( ):手势移动过程的回调
- onActionEnd( ):手势识别成功,手指抬起触发
-
代码
-
Text('这是旋转手势触发对象') .width(200) .height(300) .border({ width:1 }) //组件的旋转角度,x,y 旋转轴的坐标 angle:旋转角度 .rotate({ angle:this._DEG }) .gesture( RotationGesture() .onActionStart(() => { console.log('>>>>旋转手势被触发') }) .onActionUpdate((event) => { //用于RotationGesture手势触发场景,表示旋转角度 console.log(`>>>>${event.angle}`) this._DEG = event.angle }) )
-
滑动手势(SwiperGesture)
-
当滑动速度大于100vp/s时,可识别成功
-
有三个参数:
- **fingers:**用于声明触滑动手势最小的手指数量,最小值为1,最大值为10,默认1
- **direction:**用于声明触发滑动手势的方向,枚举值支持&& 和 ||
- speed:用于声明触发滑动最小滑动识别速度,vp/s 默认值100
-
事件
- onAction:swiper手势识别成功回调
-
代码
-
Column(){ Text(`滑动手势的速度:${this.speed}`) Text(`滑动手势的角度:${this.rotateAngle}`) } .border({ width: 3 }) .width(300) .height(200) // rotate:组的旋转,angle角度 .rotate({ angle:this.rotateAngle }) .gesture( SwipeGesture({ fingers:2 }) .onAction((event) => { console.log(`>>>>发生了滑动`) if(event){ /* * 滑动手势的速度 * 手指相对于组件原始区域滑动的评价速度 * * */ this.speed = event.speed /* * 滑动角度 * 即两个手指间的线段与水平方向的夹角变化的度数 * * */ this.rotateAngle = event.angle } }) )
-
组合手势
- 组合手势由多种单一手势组合而成,通过GestureGroup中使用不同的GestureMode来声明该组合手势的类型
- 顺序识别,并行识别,互斥识别
- GestureGroup
- mode:手势识别模式,顺序识别,并行识别,互斥识别
- Sequence 顺序识别
- Parallel 并行识别
- Exclusive 互斥识别
- guesture:手势类型 6种单一手势
- mode:手势识别模式,顺序识别,并行识别,互斥识别
顺序识别
- 组合手势按照手势的注册顺序识别手势,直到所有手势识别成功。
- 当顺序识别由一个手势识别失败,后续手势均失败。
- 在顺序识别手势组中仅有最后一个手势可以响应onActionEnd
Column(){
Text(
'组合手势\n' + '长按手势:' + this.count + '\n拖动手势偏移' +
'\n x:' + this.x + '\ny:' + this.y
)
.fontSize(28)
}
.width(250)
.height(300)
.margin(10)
.border({
width:1,
style:this.border_style
})
//偏移量
.translate({
x:this.x,
y:this.y
})
/*
* 一个有长按手势与拖动手势结合的组合手势
*
* */
//绑定手势
.gesture(
//组合手势
GestureGroup(
//声明组合手势类型为顺序识别
GestureMode.Sequence,
//第一个触发的手势为长按手势,且长按手势可以多次相应
LongPressGesture( { repeat: true } )
.onAction((event) => {
this.count++
}),
//当长按之后进行拖动,拖动手势将被触发
PanGesture()
.onActionStart(() => {
this.border_style = BorderStyle.Dashed
})
.onActionUpdate((event) => {
this.x = this.offset_x + event.offsetX
this.y = this.offset_y + event.offsetY
})
.onActionEnd(() => {
this.offset_x = this.x
this.offset_y = this.y
this.border_style = BorderStyle.Solid
})
)
.onCancel(() => {
//顺序手势没有全部执行则触发
console.log('顺序手势结束')
})
)
并行识别
- 并行识别组合手势中注册的手势将同时进行识别,直到所有手势识别结束
- 并行识别手势组合中的手势进行识别互不影响
Column(){
Text('并行事件\n' + '并行事件1:' + this.count1 +
'\n 并行事件2:' + this.count2
)
.fontSize(28)
}
.height(500)
.width('100%')
.border({
width:1
})
.justifyContent(FlexAlign.Center)
//绑定手势
.gesture(
//并行识别的组合手势
GestureGroup(
GestureMode.Parallel,
//单击手势
TapGesture({ count:1 })
.onAction(() => {
this.count1++
}),
//双击手势
TapGesture({ count:2 })
.onAction(() => {
this.count2++
})
)
)
互斥识别
- 互斥识别将组合手势中注册的手势同时识别
- 若有一个手势识别成功,则结束手势识别,其他所有手势识别失败
Column(){
Text('互斥事件\n' + '互斥事件1:' + this.count1 +
'\n 互斥事件2:' + this.count2
)
.fontSize(28)
}
.height(500)
.width('100%')
.border({
width:1
})
.justifyContent(FlexAlign.Center)
//绑定手势
.gesture(
//并行识别的组合手势
GestureGroup(
GestureMode.Exclusive,
//为什么?因为点击事件以两次点击间隔时间
// 是否大于300ms为识别界限,
// 如果小于300ms那么继续计入到点击次数中
//如果大于300ms触发对应事件
//双击手势
TapGesture({ count:4 })
.onAction(() => {
this.count2++
}),
//单击手势
TapGesture({ count:3 })
.onAction(() => {
this.count1++
}),
)
)