• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.All122
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.All329
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