手势交互
在智能设备交互体验不断升级的今天,用户对于操作的便捷性、流畅性与趣味性有了更高的期待。鸿蒙系统作为科技领域的创新先锋,一直致力于为用户打造更加智能、人性化的交互方式。其中,手势交互识别功能无疑是鸿蒙系统交互体验的一大亮点。它打破了传统单一的操作模式,通过识别用户丰富多样的手势动作,让设备与用户之间的沟通变得更加自然、高效。从简单的滑动、点击,到复杂的双指、多指操作,鸿蒙系统的手势交互识别为用户带来了全新的操作感受。今天,就让我们一起深入探索鸿蒙系统中那些丰富且实用的多种手势交互识别功能,领略其独特的魅力与强大之处。
绑定手势的方法
有三种绑定方法
gesture(常规手势绑定方法)
gesture为通用的一种手势绑定方法,可以将手势绑定到对应的组件上。
.gesture(gesture: GestureType, mask?: GestureMask)
例如,可以将点击手势TapGesture通过gesture手势将方法绑定到Text组件上。(后面介绍具体的手势事件)
@Entry
@Component
struct Index {
build() {
Column() {
Text('Gesture').fontSize(28)
// 采用gesture手势绑定方法绑定TapGesture
.gesture(
TapGesture()
.onAction(() => {
console.info('TapGesture is onAction');
}))
}
.height(200)
.width(250)
}
}
priorityGesture(带优先级的手势绑定方法)
priorityGesture是带优先级的手势绑定方法,可以在组件上绑定优先识别的手势。
解释:
当父组件和子组件使用gesture绑定同类型的手势时,子组件优先识别通过gesture绑定的手势;当父组件使用priorityGesture绑定与子组件同类型的手势时,父组件优先识别通过priorityGesture绑定的手势。
注意: 长按手势时,设置触发长按的最短时间小的组件会优先响应,会忽略priorityGesture设置。
例如,当父组件Column和子组件Text同时绑定TapGesture手势时,父组件以带优先级手势priorityGesture的形式进行绑定时,优先响应父组件绑定的TapGesture。
@Entry
@Component
struct Index {
build() {
Column() {
Text('Gesture').fontSize(28)
.gesture(
TapGesture()
.onAction(() => {
console.info('Text TapGesture is onAction');
}))
}
.height(200)
.width(250)
// 设置为priorityGesture时,点击文本区域会忽略Text组件的TapGesture手势事件,优先响应父组件Column的TapGesture手势事件
.priorityGesture(
TapGesture()
.onAction(() => {
console.info('Column TapGesture is onAction');
}), GestureMask.IgnoreInternal)
}
}
parallelGesture(并行手势绑定方法)
parallelGesture是并行的手势绑定方法,可以在父子组件上绑定可以同时响应的相同手势。无论是常规的gesture方法还是优先级的priorityGesture方法,都只能响应父子组件中的一种手势识别。而当父组件绑定了并行手势parallelGesture时,父子组件相同的手势事件都可以触发,实现类似冒泡效果。
@Entry
@Component
struct Index {
build() {
Column() {
Text('Gesture').fontSize(28)
.gesture(
TapGesture()
.onAction(() => {
console.info('Text TapGesture is onAction');
}))
}
.height(200)
.width(250)
// 设置为parallelGesture时,点击文本区域会同时响应父组件Column和子组件Text的TapGesture手势事件
.parallelGesture(
TapGesture()
.onAction(() => {
console.info('Column TapGesture is onAction');
}), GestureMask.Normal)
}
}
单一手势
6种手势
点击手势(TapGesture)
TapGesture(value?:{count?:number, fingers?:number})
点击手势支持单次点击和多次点击
有两种参数
- count:声明该点击手势识别的连续点击次数。默认值为1,若设置小于1的非法值会被转化为默认值。如果配置多次点击,上一次抬起和下一次按下的超时时间为300毫秒。
- fingers:用于声明触发点击的手指数量,最小值为1,最大值为10,默认值为1。当配置多指时,若第一根手指按下300毫秒内未有足够的手指数按下则手势识别失败。
在Text组件上绑定双击手势(count值为2的点击手势)
// xxx.ets
@Entry
@Component
struct Index {
@State value: string = "";
build() {
Column() {
Text('Click twice').fontSize(28)
.gesture(
// 绑定count为2的TapGesture
TapGesture({ count: 2 })
.onAction((event: GestureEvent|undefined) => {
if(event){
promptAction.showToast({message:'点击'})
}
}))
}
.height(200)
.width(250)
.padding(20)
.border({ width: 3 })
.margin(30)
}
}
长按手势(LongPressGesture)
LongPressGesture(value?:{fingers?:number, repeat?:boolean, duration?:number})
长按手势用于触发长按手势事件
三个可选参数
- fingers:用于声明触发长按手势所需要的最少手指数量,最小值为1,最大值为10,默认值为1。
- repeat:用于声明是否连续触发事件回调,默认值为false。
- duration:用于声明触发长按所需的最短时间,单位为毫秒,默认值为500。
事件
属性
示例
@Entry
@Component
struct Index {
build() {
Column() {
// 单指长按文本触发该手势事件
Text('长按手势事件')
.gesture(
LongPressGesture({ repeat: true })
.onAction(() => {
// 由于repeat设置为true,长按动作存在时会连续触发,触发间隔为duration(默认值500ms)
console.log('长按触发')
})
.onActionEnd(() => {
// 长按动作一结束触发
console.log(`长按取消`)
})
)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
拖动手势(PanGesture)
又叫滑动手势事件,当滑动的最小距离达到设定的最小值时触发滑动手势事件
- fingers:用于声明触发拖动手势所需要的最少手指数量,最小值为1,最大值为10,默认值为1。
- direction:用于声明触发拖动的手势方向,此枚举值支持逻辑与(&)和逻辑或(|)运算。默认值为Pandirection.All。 (PanDirection枚举说明)
- distance:用于声明触发拖动的最小拖动识别距离,单位为vp,默认值为5。
事件
示例
@Entry
@Component
struct PanGesturePage {
@State offsetX: number = 0
@State offsetY: number = 0
@State positionX: number = 0
@State positionY: number = 0
build() {
Column() {
Row()
.width(50)
.height(50)
.borderRadius(25)
.backgroundColor(Color.Pink)
.translate({ x: this.offsetX, y: this.offsetY, z: 0 })// 以组件左上角为坐标原点进行移动
.gesture(
PanGesture()
.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')
})
)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
效果
后续
还有三种手势交互以及组合手势的用法,同时也会介绍手势拦截!!!!