1# 单一手势 2 3 4## 点击手势(TapGesture) 5 6 7```ts 8TapGesture(value?:{count?:number; fingers?:number}) 9``` 10 11 12点击手势支持单次点击和多次点击,拥有两个可选参数: 13 14 15- count:非必填参数,声明该点击手势识别的连续点击次数。默认值为1,若设置小于1的非法值会被转化为默认值。如果配置多次点击,上一次抬起和下一次按下的超时时间为300毫秒。 16 17- fingers:非必填参数,用于声明触发点击的手指数量,最小值为1,最大值为10,默认值为1。当配置多指时,若第一根手指按下300毫秒内未有足够的手指数按下则手势识别失败。当实际点击手指数超过配置值时,手势识别失败。 18 以在Text组件上绑定双击手势(count值为2的点击手势)为例: 19 20 ```ts 21 // xxx.ets 22 @Entry 23 @Component 24 struct Index { 25 @State value: string = ""; 26 27 build() { 28 Column() { 29 Text('Click twice').fontSize(28) 30 .gesture( 31 // 绑定count为2的TapGesture 32 TapGesture({ count: 2 }) 33 .onAction((event: GestureEvent) => { 34 this.value = JSON.stringify(event.fingerList[0]); 35 })) 36 Text(this.value) 37 } 38 .height(200) 39 .width(250) 40 .padding(20) 41 .border({ width: 3 }) 42 .margin(30) 43 } 44 } 45 ``` 46 47 ![tap](figures/tap.gif) 48 49 50## 长按手势(LongPressGesture) 51 52 53```ts 54LongPressGesture(value?:{fingers?:number; repeat?:boolean; duration?:number}) 55``` 56 57 58长按手势用于触发长按手势事件,触发长按手势的最少手指数量为1,最短长按事件为500毫秒,拥有三个可选参数: 59 60 61- fingers:非必选参数,用于声明触发长按手势所需要的最少手指数量,最小值为1,最大值为10,默认值为1。 62 63- repeat:非必选参数,用于声明是否连续触发事件回调,默认值为false。 64 65- duration:非必选参数,用于声明触发长按所需的最短时间,单位为毫秒,默认值为500。 66 67 68以在Text组件上绑定可以重复触发的长按手势为例: 69 70 71 72```ts 73// xxx.ets 74@Entry 75@Component 76struct Index { 77 @State count: number = 0; 78 79 build() { 80 Column() { 81 Text('LongPress OnAction:' + this.count).fontSize(28) 82 .gesture( 83 // 绑定可以重复触发的LongPressGesture 84 LongPressGesture({ repeat: true }) 85 .onAction((event: GestureEvent) => { 86 if (event.repeat) { 87 this.count++; 88 } 89 }) 90 .onActionEnd(() => { 91 this.count = 0; 92 }) 93 ) 94 } 95 .height(200) 96 .width(250) 97 .padding(20) 98 .border({ width: 3 }) 99 .margin(30) 100 } 101} 102``` 103 104 105![longPress](figures/longPress.gif) 106 107 108## 拖动手势(PanGesture) 109 110 111```ts 112PanGestureOptions(value?:{ fingers?:number; direction?:PanDirection; distance?:number}) 113``` 114 115 116拖动手势用于触发拖动手势事件,滑动达到最小滑动距离(默认值为5vp)时拖动手势识别成功,拥有三个可选参数: 117 118 119- fingers:非必选参数,用于声明触发拖动手势所需要的最少手指数量,最小值为1,最大值为10,默认值为1。 120 121- direction:非必选参数,用于声明触发拖动的手势方向,此枚举值支持逻辑与(&)和逻辑或(|)运算。默认值为Pandirection.All。 122 123- distance:非必选参数,用于声明触发拖动的最小拖动识别距离,单位为vp,默认值为5。 124 125 126以在Text组件上绑定拖动手势为例,可以通过在拖动手势的回调函数中修改组件的布局位置信息来实现组件的拖动: 127 128 129 130```ts 131// xxx.ets 132@Entry 133@Component 134struct Index { 135 @State offsetX: number = 0; 136 @State offsetY: number = 0; 137 @State positionX: number = 0; 138 @State positionY: number = 0; 139 140 build() { 141 Column() { 142 Text('PanGesture Offset:\nX: ' + this.offsetX + '\n' + 'Y: ' + this.offsetY) 143 .fontSize(28) 144 .height(200) 145 .width(300) 146 .padding(20) 147 .border({ width: 3 }) 148 // 在组件上绑定布局位置信息 149 .translate({ x: this.offsetX, y: this.offsetY, z: 0 }) 150 .gesture( 151 // 绑定拖动手势 152 PanGesture() 153 .onActionStart((event: GestureEvent) => { 154 console.info('Pan start'); 155 }) 156 // 当触发拖动手势时,根据回调函数修改组件的布局位置信息 157 .onActionUpdate((event: GestureEvent) => { 158 this.offsetX = this.positionX + event.offsetX; 159 this.offsetY = this.positionY + event.offsetY; 160 }) 161 .onActionEnd(() => { 162 this.positionX = this.offsetX; 163 this.positionY = this.offsetY; 164 }) 165 ) 166 } 167 .height(200) 168 .width(250) 169 } 170} 171``` 172 173 174![pan](figures/pan.gif) 175 176 177>**说明:** 178> 179>大部分可滑动组件,如List、Grid、Scroll、Tab等组件是通过PanGesture实现滑动,在组件内部的子组件绑定[拖动手势(PanGesture)](#拖动手势pangesture)或者[滑动手势(SwipeGesture)](#滑动手势swipegesture)会导致手势竞争。 180> 181>当在子组件绑定PanGesture时,在子组件区域进行滑动仅触发子组件的PanGesture。如果需要父组件响应,需要通过修改手势绑定方法或者子组件向父组件传递消息进行实现,或者通过修改父子组件的PanGesture参数distance使得拖动更灵敏。当子组件绑定SwipeGesture时,由于PanGesture和SwipeGesture触发条件不同,需要修改PanGesture和SwipeGesture的参数以达到所需效果。 182 183 184## 捏合手势(PinchGesture) 185 186 187```ts 188PinchGesture(value?:{fingers?:number; distance?:number}) 189``` 190 191 192捏合手势用于触发捏合手势事件,触发捏合手势的最少手指数量为2指,最大为5指,最小识别距离为3vp,拥有两个可选参数: 193 194 195- fingers:非必选参数,用于声明触发捏合手势所需要的最少手指数量,最小值为2,最大值为5,默认值为2。 196 197- distance:非必选参数,用于声明触发捏合手势的最小距离,单位为vp,默认值为3。 198 199 200以在Column组件上绑定三指捏合手势为例,可以通过在捏合手势的函数回调中获取缩放比例,实现对组件的缩小或放大: 201 202 203 204```ts 205// xxx.ets 206@Entry 207@Component 208struct Index { 209 @State scaleValue: number = 1; 210 @State pinchValue: number = 1; 211 @State pinchX: number = 0; 212 @State pinchY: number = 0; 213 214 build() { 215 Column() { 216 Column() { 217 Text('PinchGesture scale:\n' + this.scaleValue) 218 Text('PinchGesture center:\n(' + this.pinchX + ',' + this.pinchY + ')') 219 } 220 .height(200) 221 .width(300) 222 .border({ width: 3 }) 223 .margin({ top: 100 }) 224 // 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大 225 .scale({ x: this.scaleValue, y: this.scaleValue, z: 1 }) 226 .gesture( 227 // 在组件上绑定三指触发的捏合手势 228 PinchGesture({ fingers: 3 }) 229 .onActionStart((event: GestureEvent) => { 230 console.info('Pinch start'); 231 }) 232 // 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例 233 .onActionUpdate((event: GestureEvent) => { 234 this.scaleValue = this.pinchValue * event.scale; 235 this.pinchX = event.pinchCenterX; 236 this.pinchY = event.pinchCenterY; 237 }) 238 .onActionEnd(() => { 239 this.pinchValue = this.scaleValue; 240 console.info('Pinch end'); 241 }) 242 ) 243 } 244 } 245} 246``` 247 248 249![pinch](figures/pinch.png) 250 251 252## 旋转手势(RotationGesture) 253 254 255```ts 256RotationGesture(value?:{fingers?:number; angle?:number}) 257``` 258 259 260旋转手势用于触发旋转手势事件,触发旋转手势的最少手指数量为2指,最大为5指,最小改变度数为1度,拥有两个可选参数: 261 262 263- fingers:非必选参数,用于声明触发旋转手势所需要的最少手指数量,最小值为2,最大值为5,默认值为2。 264 265- angle:非必选参数,用于声明触发旋转手势的最小改变度数,单位为deg,默认值为1。 266 267 268以在Text组件上绑定旋转手势实现组件的旋转为例,可以通过在旋转手势的回调函数中获取旋转角度,从而实现组件的旋转: 269 270 271 272```ts 273// xxx.ets 274@Entry 275@Component 276struct Index { 277 @State angle: number = 0; 278 @State rotateValue: number = 0; 279 280 build() { 281 Column() { 282 Text('RotationGesture angle:' + this.angle).fontSize(28) 283 // 在组件上绑定旋转布局,可以通过修改旋转角度来实现组件的旋转 284 .rotate({ angle: this.angle }) 285 .gesture( 286 RotationGesture() 287 .onActionStart((event: GestureEvent) => { 288 console.info('RotationGesture is onActionStart'); 289 }) 290 // 当旋转手势生效时,通过旋转手势的回调函数获取旋转角度,从而修改组件的旋转角度 291 .onActionUpdate((event: GestureEvent) => { 292 this.angle = this.rotateValue + event.angle; 293 console.info('RotationGesture is onActionEnd'); 294 }) 295 // 当旋转结束抬手时,固定组件在旋转结束时的角度 296 .onActionEnd(() => { 297 this.rotateValue = this.angle; 298 console.info('RotationGesture is onActionEnd'); 299 }) 300 .onActionCancel(() => { 301 console.info('RotationGesture is onActionCancel'); 302 }) 303 ) 304 } 305 .height(200) 306 .width(250) 307 } 308} 309``` 310 311 312![rotation](figures/rotation.png) 313 314 315## 滑动手势(SwipeGesture) 316 317 318```ts 319SwipeGesture(value?:{fingers?:number; direction?:SwipeDirection; speed?:number}) 320``` 321 322 323滑动手势用于触发滑动事件,当滑动速度大于100vp/s时可以识别成功,拥有三个可选参数: 324 325 326- fingers:非必选参数,用于声明触发滑动手势所需要的最少手指数量,最小值为1,最大值为10,默认值为1。 327 328- direction:非必选参数,用于声明触发滑动手势的方向,此枚举值支持逻辑与(&)和逻辑或(|)运算。默认值为SwipeDirection.All。 329 330- speed:非必选参数,用于声明触发滑动的最小滑动识别速度,单位为vp/s,默认值为100。 331 332 333以在Column组件上绑定滑动手势实现组件的旋转为例: 334 335 336 337```ts 338// xxx.ets 339@Entry 340@Component 341struct Index { 342 @State rotateAngle: number = 0; 343 @State speed: number = 1; 344 345 build() { 346 Column() { 347 Column() { 348 Text("SwipeGesture speed\n" + this.speed) 349 Text("SwipeGesture angle\n" + this.rotateAngle) 350 } 351 .border({ width: 3 }) 352 .width(300) 353 .height(200) 354 .margin(100) 355 // 在Column组件上绑定旋转,通过滑动手势的滑动速度和角度修改旋转的角度 356 .rotate({ angle: this.rotateAngle }) 357 .gesture( 358 // 绑定滑动手势且限制仅在竖直方向滑动时触发 359 SwipeGesture({ direction: SwipeDirection.Vertical }) 360 // 当滑动手势触发时,获取滑动的速度和角度,实现对组件的布局参数的修改 361 .onAction((event: GestureEvent) => { 362 this.speed = event.speed; 363 this.rotateAngle = event.angle; 364 }) 365 ) 366 } 367 } 368} 369``` 370 371 372![swipe](figures/swipe.gif) 373 374 375>**说明:** 376> 377>当SwipeGesture和PanGesture同时绑定时,若二者是以默认方式或者互斥方式进行绑定时,会发生竞争。SwipeGesture的触发条件为滑动速度达到100vp/s,PanGesture的触发条件为滑动距离达到5vp,先达到触发条件的手势触发。可以通过修改SwipeGesture和PanGesture的参数以达到不同的效果。 378