• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 手势拦截增强
2
3为组件提供手势拦截能力。开发者可根据需要,将系统内置手势和比其优先级高的手势做并行化处理,并可以动态控制手势事件的触发。
4
5>  **说明:**
6>
7>  从API Version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8
9## shouldBuiltInRecognizerParallelWith
10
11shouldBuiltInRecognizerParallelWith(callback: ShouldBuiltInRecognizerParallelWithCallback): T
12
13提供系统内置手势与响应链上其他组件的手势设置并行关系的回调事件。
14
15**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
16
17**系统能力:** SystemCapability.ArkUI.ArkUI.Full
18
19**参数:**
20| 参数名        | 参数类型                    | 必填  | 参数描述                          |
21| ---------- | -------------------------- | ------- | ----------------------------- |
22| callback      | [ShouldBuiltInRecognizerParallelWithCallback](#shouldbuiltinrecognizerparallelwithcallback) | 是   |  提供系统内置手势与响应链上其他组件的手势设置并行关系的回调事件,当该组件做触摸碰撞测试时,会触发用户定义的回调来形成手势并行关系。 |
23
24**返回值:**
25
26| 类型 | 说明 |
27| -------- | -------- |
28| T | 返回当前组件。 |
29
30## ShouldBuiltInRecognizerParallelWithCallback
31
32type ShouldBuiltInRecognizerParallelWithCallback = (current: GestureRecognizer, others: Array\<GestureRecognizer\>) => GestureRecognizer
33
34提供系统内置手势与响应链上其他组件的手势设置并行关系的回调事件类型。
35
36**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
37
38**系统能力:** SystemCapability.ArkUI.ArkUI.Full
39
40**参数:**
41
42| 参数名   | 类型                      | 必填 | 说明                                                         |
43| -------- | ------------------------- | ---- | ------------------------------------------------------------ |
44| current | [GestureRecognizer](#gesturerecognizer) | 是   | 当前组件的系统内置手势识别器,当前版本只提供内置的[PAN_GESTURE](ts-gesture-customize-judge.md#gesturejudgeresult11)类型的手势识别器。 |
45| others | Array\<[GestureRecognizer](#gesturerecognizer)\> | 是   | 响应链上更高优先级的其他组件相同类别的手势识别器。 |
46
47**返回值:**
48
49| 类型     | 说明        |
50| ------ | --------- |
51| [GestureRecognizer](#gesturerecognizer) | 与current识别器绑定并行关系的某个手势识别器。 |
52
53## GestureRecognizer
54
55手势识别器对象。
56
57### getTag
58
59getTag(): string
60
61返回当前手势识别器的tag。
62
63**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
64
65**系统能力:** SystemCapability.ArkUI.ArkUI.Full
66
67**返回值:**
68
69| 类型     | 说明        |
70| ------ | --------- |
71| string | 当前手势识别器的tag。 |
72
73### getType
74
75getType(): GestureControl.GestureType
76
77返回当前手势识别器的类型。
78
79**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
80
81**系统能力:** SystemCapability.ArkUI.ArkUI.Full
82
83**返回值:**
84
85| 类型     | 说明        |
86| ------ | --------- |
87| [GestureControl.GestureType](ts-gesture-customize-judge.md#gesturetype12) | 当前手势识别器的类型。 |
88
89### isBuiltIn
90
91isBuiltIn(): boolean
92
93返回当前手势识别器是否为系统内置手势。
94
95**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
96
97**系统能力:** SystemCapability.ArkUI.ArkUI.Full
98
99**返回值:**
100
101| 类型     | 说明        |
102| ------ | --------- |
103| boolean | 当前手势识别器是否为系统内置手势。true表示手势识别器为系统内置手势,false表示非系统内置手势。 |
104
105### setEnabled
106
107setEnabled(isEnabled: boolean): void
108
109设置当前手势识别器的使能状态。
110
111**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
112
113**系统能力:** SystemCapability.ArkUI.ArkUI.Full
114
115**参数:**
116
117| 参数名     | 类型                           | 必填   | 说明  |
118| ------- | ---------------------------------- | ---- | ----- |
119| isEnabled   | boolean         | 是    | 手势识别器的使能状态。true表示当前手势识别器能够回调应用事件,false表示当前手势识别器不回调应用事件。 |
120
121### isEnabled
122
123isEnabled(): boolean
124
125返回当前手势识别器的使能状态。
126
127**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
128
129**系统能力:** SystemCapability.ArkUI.ArkUI.Full
130
131**返回值:**
132
133| 类型     | 说明        |
134| ------ | --------- |
135| boolean | 当前手势识别器的使能状态。true表示当前手势识别器能够回调应用事件,false表示当前手势识别器不回调应用事件。 |
136
137### getState
138
139getState(): GestureRecognizerState
140
141返回当前手势识别器的状态。
142
143**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
144
145**系统能力:** SystemCapability.ArkUI.ArkUI.Full
146
147**返回值:**
148
149| 类型     | 说明        |
150| ------ | --------- |
151| [GestureRecognizerState](#gesturerecognizerstate) | 当前手势识别器的状态。 |
152
153### getEventTargetInfo
154
155getEventTargetInfo(): EventTargetInfo
156
157返回当前手势识别器对应组件的信息。
158
159**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
160
161**系统能力:** SystemCapability.ArkUI.ArkUI.Full
162
163**返回值:**
164
165| 类型     | 说明        |
166| ------ | --------- |
167| [EventTargetInfo](#eventtargetinfo) | 当前手势识别器对应组件的信息。 |
168
169### isValid
170
171isValid(): boolean;
172
173返回当前手势识别器是否有效。
174
175**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
176
177**系统能力:** SystemCapability.ArkUI.ArkUI.Full
178
179**返回值:**
180
181| 类型     | 说明        |
182| ------ | --------- |
183| boolean | 当前手势识别器是否有效。当该识别器绑定的组件被析构或者该识别器不在响应链上时返回false。 |
184
185### getFingerCount<sup>18+</sup>
186
187getFingerCount(): number
188
189返回预设手指识别数阈值。
190
191**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
192
193**系统能力:** SystemCapability.ArkUI.ArkUI.Full
194
195**返回值:**
196
197| 类型     | 说明        |
198| ------ | --------- |
199| number | 预设手指识别数阈值。<br/>取值范围:[1, 10], 整数。 |
200
201### isFingerCountLimit<sup>18+</sup>
202
203isFingerCountLimit(): boolean
204
205返回预设手势是否会检测触摸屏幕上手指识别数量。
206
207**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
208
209**系统能力:** SystemCapability.ArkUI.ArkUI.Full
210
211**返回值:**
212
213| 类型     | 说明        |
214| ------ | --------- |
215| boolean | 预设手势是否会检测触摸屏幕上手指识别数量。当绑定手势事件且会检测触摸屏幕上手指的数量时,返回true。当绑定手势事件且不会检测触摸屏幕上手指的数量时,返回false。 |
216
217## GestureRecognizerState
218
219定义手势识别器状态。
220
221**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
222
223**系统能力:** SystemCapability.ArkUI.ArkUI.Full
224
225| 名称    | 值   | 描述                               |
226| ------- | ---- | ---------------------------------- |
227| READY | 0    | 准备状态。 |
228| DETECTING    | 1    | 检测状态。 |
229| PENDING    | 2    | 等待状态。 |
230| BLOCKED    | 3    | 阻塞状态。 |
231| SUCCESSFUL    | 4    | 成功状态。 |
232| FAILED    | 5    | 失败状态。 |
233
234## EventTargetInfo
235
236手势识别器对应组件的信息。
237
238### getId
239
240getId(): string
241
242返回当前组件的组件标识。
243
244**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
245
246**系统能力:** SystemCapability.ArkUI.ArkUI.Full
247
248**返回值:**
249
250| 类型     | 说明        |
251| ------ | --------- |
252| string | 当前组件的[组件标识](./ts-universal-attributes-component-id.md#id)。 |
253
254## ScrollableTargetInfo
255
256手势识别器对应的滚动类容器组件的信息,继承于[EventTargetInfo](#eventtargetinfo)。
257
258### isBegin
259
260isBegin(): boolean
261
262返回当前滚动类容器组件是否在顶部,如果为Swiper组件且在循环模式下返回false。
263
264**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
265
266**系统能力:** SystemCapability.ArkUI.ArkUI.Full
267
268**返回值:**
269
270| 类型     | 说明        |
271| ------ | --------- |
272| boolean | 当前滚动类容器组件是否在顶部。true表示组件在顶部,false表示组件不在顶部。 |
273
274### isEnd
275
276isEnd(): boolean
277
278返回当前滚动类容器组件是否在底部,如果为Swiper组件且在循环模式下返回false。
279
280**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
281
282**系统能力:** SystemCapability.ArkUI.ArkUI.Full
283
284**返回值:**
285
286| 类型     | 说明        |
287| ------ | --------- |
288| boolean | 当前滚动类容器组件是否在底部。true表示组件在底部,false表示组件不在底部。 |
289
290## PanRecognizer
291
292拖动手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
293
294### getPanGestureOptions
295
296getPanGestureOptions(): PanGestureOptions
297
298返回当前拖动手势识别器的属性。
299
300**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
301
302**系统能力:** SystemCapability.ArkUI.ArkUI.Full
303
304**返回值:**
305
306| 类型     | 说明        |
307| ------ | --------- |
308| [PanGestureOptions](./ts-basic-gestures-pangesture.md#pangestureoptions) | 当前拖动手势识别器的属性。 |
309
310## TapRecognizer<sup>18+</sup>
311
312点击手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
313
314### getTapCount<sup>18+</sup>
315
316getTapCount(): number
317
318返回预设点击手势识别器连续点击次数阈值。
319
320**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
321
322**系统能力:** SystemCapability.ArkUI.ArkUI.Full
323
324**返回值:**
325
326| 类型     | 说明        |
327| ------ | --------- |
328| number | 预设点击手势识别器连续点击次数阈值。<br/>取值范围:[0, +∞) |
329
330## LongPressRecognizer<sup>18+</sup>
331
332长按手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
333
334### isRepeat<sup>18+</sup>
335
336isRepeat(): boolean
337
338返回预设长按手势识别器是否连续触发事件回调。
339
340**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
341
342**系统能力:** SystemCapability.ArkUI.ArkUI.Full
343
344**返回值:**
345
346| 类型     | 说明        |
347| ------ | --------- |
348| boolean | 预设长按手势识别器是否连续触发事件回调。当绑定长按手势且不会连续触发回调时,返回false。当绑定长按手势且会连续触发回调时,返回true。 |
349
350### getDuration<sup>18+</sup>
351
352getDuration(): number
353
354返回预设长按手势识别器触发长按最短时间阈值。
355
356**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
357
358**系统能力:** SystemCapability.ArkUI.ArkUI.Full
359
360**返回值:**
361
362| 类型     | 说明        |
363| ------ | --------- |
364| number | 预设长按手势识别器触发长按最短时间阈值,单位为ms。<br/>取值范围:[0, +∞) |
365
366## SwipeRecognizer<sup>18+</sup>
367
368滑动手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
369
370### getVelocityThreshold<sup>18+</sup>
371
372getVelocityThreshold(): number
373
374返回预设滑动手势识别器识别滑动最小速度阈值。
375
376**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
377
378**系统能力:** SystemCapability.ArkUI.ArkUI.Full
379
380**返回值:**
381
382| 类型     | 说明        |
383| ------ | --------- |
384| number | 预设滑动手势识别器识别滑动最小速度阈值,单位为vp/s。<br/>取值范围:[0, +∞) |
385
386### getDirection<sup>18+</sup>
387
388getDirection(): SwipeDirection
389
390返回预设滑动手势识别器触发滑动手势滑动方向阈值。
391
392**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
393
394**系统能力:** SystemCapability.ArkUI.ArkUI.Full
395
396**返回值:**
397
398| 类型     | 说明        |
399| ------ | --------- |
400| [SwipeDirection](./ts-basic-gestures-swipegesture.md#swipedirection枚举说明) | 预设滑动手势识别器触发滑动手势滑动方向阈值。 |
401
402## PinchRecognizer<sup>18+</sup>
403
404捏合手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
405
406### getDistance<sup>18+</sup>
407
408getDistance(): number
409
410返回预设捏合手势识别器最小识别距离阈值。
411
412**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
413
414**系统能力:** SystemCapability.ArkUI.ArkUI.Full
415
416**返回值:**
417
418| 类型     | 说明        |
419| ------ | --------- |
420| number | 预设捏合手势识别器最小识别距离阈值,单位为vp。<br/>取值范围:[0, +∞) |
421
422## RotationRecognizer<sup>18+</sup>
423
424旋转手势识别器对象,继承于[GestureRecognizer](#gesturerecognizer)。
425
426### getAngle<sup>18+</sup>
427
428getAngle(): number
429
430返回预设旋转手势识别器触发旋转手势最小改变度数阈值。
431
432**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
433
434**系统能力:** SystemCapability.ArkUI.ArkUI.Full
435
436**返回值:**
437
438| 类型     | 说明        |
439| ------ | --------- |
440| number | 预设旋转手势识别器触发旋转手势最小改变度数阈值,单位为deg。<br/>取值范围:[0, +∞)<br/>**说明:** <br/>当输入的改变度数的值小于等于0或大于360时,会被转化为默认值,默认值为1。 |
441
442## onGestureRecognizerJudgeBegin<sup>13+</sup>
443
444onGestureRecognizerJudgeBegin(callback: GestureRecognizerJudgeBeginCallback, exposeInnerGesture: boolean): T
445
446给组件绑定自定义手势识别器判定回调。
447
448新增exposeInnerGesture参数作为是否将回调暴露给ArkUI系统组合组件的内置组件的标识,当该标识置为true时,将回调暴露给ArkUI系统组合组件的内置组件。<br>
449对于不需要将回调暴露给ArkUI系统组合组件内置组件的场景,建议采用原有[onGestureRecognizerJudgeBegin](#ongesturerecognizerjudgebegin)接口。若要求将回调暴露给ArkUI系统组合组件的内置组件,建议使用该接口并将exposeInnerGesture设置为true。
450
451**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。
452
453**系统能力:** SystemCapability.ArkUI.ArkUI.Full
454
455**参数:**
456| 参数名        | 参数类型                    | 必填  | 参数描述                          |
457| ---------- | -------------------------- | ------- | ----------------------------- |
458| callback      | [GestureRecognizerJudgeBeginCallback](#gesturerecognizerjudgebegincallback) | 是     |  给组件绑定自定义手势识别器判定回调,当绑定到该组件的手势被接受时,会触发用户定义的回调来获取结果。 |
459| exposeInnerGesture   | boolean         | 是    | 暴露内部手势标识。<br/>默认值:false<br/>**说明:**<br/>如果是组合组件,此参数设置true,则会在current参数回调出组合组件内部的手势识别器。<br>当前仅支持[Tabs](ts-container-tabs.md),其他组件请不要设置此参数。<br/>设置为false时,功能与原接口[onGestureRecognizerJudgeBegin](#ongesturerecognizerjudgebegin)相同。 |
460
461## onGestureRecognizerJudgeBegin
462
463onGestureRecognizerJudgeBegin(callback: GestureRecognizerJudgeBeginCallback): T
464
465给组件绑定自定义手势识别器判定回调。
466
467**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
468
469**系统能力:** SystemCapability.ArkUI.ArkUI.Full
470
471**参数:**
472| 参数名        | 参数类型                    | 必填  | 参数描述                          |
473| ---------- | -------------------------- | ------- | ----------------------------- |
474| callback      | [GestureRecognizerJudgeBeginCallback](#gesturerecognizerjudgebegincallback) | 是     |  给组件绑定自定义手势识别器判定回调,当绑定到该组件的手势被接受时,会触发用户定义的回调来获取结果。 |
475
476**返回值:**
477
478| 类型 | 说明 |
479| -------- | -------- |
480| T | 返回当前组件。 |
481
482## GestureRecognizerJudgeBeginCallback
483
484type GestureRecognizerJudgeBeginCallback = (event: BaseGestureEvent, current: GestureRecognizer, recognizers: Array\<GestureRecognizer\>) => GestureJudgeResult
485
486自定义手势识别器判定回调类型。
487
488**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
489
490**系统能力:** SystemCapability.ArkUI.ArkUI.Full
491
492**参数:**
493
494| 参数名   | 类型                      | 必填 | 说明                                                         |
495| -------- | ------------------------- | ---- | ------------------------------------------------------------ |
496| event | [BaseGestureEvent](./ts-gesture-customize-judge.md#basegestureevent对象说明) | 是   | 当前基础手势事件信息。 |
497| current | [GestureRecognizer](#gesturerecognizer) | 是   | 当前即将要响应的识别器对象。 |
498| others | Array\<[GestureRecognizer](#gesturerecognizer)\> | 是   | 响应链上的其他手势识别器对象。 |
499
500**返回值:**
501
502| 类型     | 说明        |
503| ------ | --------- |
504| [GestureJudgeResult](ts-gesture-customize-judge.md#gesturejudgeresult11) | 手势是否裁决成功的判定结果。 |
505
506## 示例
507
508### 示例1(嵌套滚动)
509
510该示例通过shouldBuiltInrecognizerParallelWith和onGestureRecognizerJudgeBegin实现了嵌套滚动的功能。内部组件优先响应滑动手势,当内部组件滑动至顶部或底部时,外部组件能够接替滑动。
511
512```ts
513// xxx.ets
514@Entry
515@Component
516struct FatherControlChild {
517  scroller: Scroller = new Scroller()
518  scroller2: Scroller = new Scroller()
519  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
520  private childRecognizer: GestureRecognizer = new GestureRecognizer()
521  private currentRecognizer: GestureRecognizer = new GestureRecognizer()
522  private lastOffset: number = 0
523
524  build() {
525    Stack({ alignContent: Alignment.TopStart }) {
526      Scroll(this.scroller) { // 外部滚动容器
527        Column() {
528          Text("Scroll Area")
529            .width('90%')
530            .height(150)
531            .backgroundColor(0xFFFFFF)
532            .borderRadius(15)
533            .fontSize(16)
534            .textAlign(TextAlign.Center)
535            .margin({ top: 10 })
536          Scroll(this.scroller2) { // 内部滚动容器
537            Column() {
538              Text("Scroll Area2")
539                .width('90%')
540                .height(150)
541                .backgroundColor(0xFFFFFF)
542                .borderRadius(15)
543                .fontSize(16)
544                .textAlign(TextAlign.Center)
545                .margin({ top: 10 })
546              Column() {
547                ForEach(this.arr, (item: number) => {
548                  Text(item.toString())
549                    .width('90%')
550                    .height(150)
551                    .backgroundColor(0xFFFFFF)
552                    .borderRadius(15)
553                    .fontSize(16)
554                    .textAlign(TextAlign.Center)
555                    .margin({ top: 10 })
556                }, (item: string) => item)
557              }.width('100%')
558            }
559          }
560          .id("inner")
561          .width('100%')
562          .height(800)
563        }.width('100%')
564      }
565      .id("outer")
566      .height(600)
567      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
568      .scrollBar(BarState.On) // 滚动条常驻显示
569      .scrollBarColor(Color.Gray) // 滚动条颜色
570      .scrollBarWidth(10) // 滚动条宽度
571      .edgeEffect(EdgeEffect.None)
572      .shouldBuiltInRecognizerParallelWith((current: GestureRecognizer, others: Array<GestureRecognizer>) => {
573        for (let i = 0; i < others.length; i++) {
574          let target = others[i].getEventTargetInfo();
575          if (target) {
576            if (target.getId() == "inner" && others[i].isBuiltIn() && others[i].getType() == GestureControl.GestureType.PAN_GESTURE) { // 找到将要组成并行手势的识别器
577              this.currentRecognizer = current; // 保存当前组件的识别器
578              this.childRecognizer = others[i]; // 保存将要组成并行手势的识别器
579              return others[i]; // 返回将要组成并行手势的识别器
580            }
581          }
582        }
583        return undefined;
584      })
585      .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, others: Array<GestureRecognizer>) => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态
586        if (current) {
587          let target = current.getEventTargetInfo();
588          if (target) {
589            if (target.getId() == "outer" && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) {
590              if (others) {
591                for (let i = 0; i < others.length; i++) {
592                  let target = others[i].getEventTargetInfo() as ScrollableTargetInfo;
593                  if (target instanceof ScrollableTargetInfo && target.getId() == "inner") { // 找到响应链上对应并行的识别器
594                    let panEvent = event as PanGestureEvent;
595                    if (target.isEnd()) { // 根据当前组件状态以及移动方向动态控制识别器使能状态
596                      if (panEvent && panEvent.offsetY < 0) {
597                        this.childRecognizer.setEnabled(false)
598                        this.currentRecognizer.setEnabled(true)
599                      } else {
600                        this.childRecognizer.setEnabled(true)
601                        this.currentRecognizer.setEnabled(false)
602                      }
603                    } else if (target.isBegin()) {
604                      if (panEvent.offsetY > 0) {
605                        this.childRecognizer.setEnabled(false)
606                        this.currentRecognizer.setEnabled(true)
607                      } else {
608                        this.childRecognizer.setEnabled(true)
609                        this.currentRecognizer.setEnabled(false)
610                      }
611                    } else {
612                      this.childRecognizer.setEnabled(true)
613                      this.currentRecognizer.setEnabled(false)
614                    }
615                  }
616                }
617              }
618            }
619          }
620        }
621        return GestureJudgeResult.CONTINUE;
622      })
623      .parallelGesture( // 绑定一个Pan手势作为动态控制器
624        PanGesture()
625          .onActionUpdate((event: GestureEvent)=>{
626            if (this.childRecognizer.getState() != GestureRecognizerState.SUCCESSFUL || this.currentRecognizer.getState() != GestureRecognizerState.SUCCESSFUL) { // 如果识别器状态不是SUCCESSFUL,则不做控制
627              return;
628            }
629            let target = this.childRecognizer.getEventTargetInfo() as ScrollableTargetInfo;
630            let currentTarget = this.currentRecognizer.getEventTargetInfo() as ScrollableTargetInfo;
631            if (target instanceof ScrollableTargetInfo && currentTarget instanceof ScrollableTargetInfo) {
632              if (target.isEnd()) { // 在移动过程中实时根据当前组件状态,控制识别器的开闭状态
633                if ((event.offsetY - this.lastOffset) < 0) {
634                  this.childRecognizer.setEnabled(false)
635                  if (currentTarget.isEnd()) {
636                    this.currentRecognizer.setEnabled(false)
637                  } else {
638                    this.currentRecognizer.setEnabled(true)
639                  }
640                } else {
641                  this.childRecognizer.setEnabled(true)
642                  this.currentRecognizer.setEnabled(false)
643                }
644              } else if (target.isBegin()) {
645                if ((event.offsetY - this.lastOffset) > 0) {
646                  this.childRecognizer.setEnabled(false)
647                  if (currentTarget.isBegin()) {
648                    this.currentRecognizer.setEnabled(false)
649                  } else {
650                    this.currentRecognizer.setEnabled(true)
651                  }
652                } else {
653                  this.childRecognizer.setEnabled(true)
654                  this.currentRecognizer.setEnabled(false)
655                }
656              } else {
657                this.childRecognizer.setEnabled(true)
658                this.currentRecognizer.setEnabled(false)
659              }
660            }
661            this.lastOffset = event.offsetY
662          })
663      )
664    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
665  }
666}
667```
668
669### 示例2(嵌套场景下拦截内部容器手势)
670
671本示例通过将参数exposeInnerGesture设置为true,实现了一级Tabs容器在嵌套二级Tabs的场景下,能够屏蔽二级Tabs内置Swiper的滑动手势,从而触发一级Tabs内置Swiper滑动手势的功能。
672开发者自行定义变量来记录内层Tabs的索引值,通过该索引值判断当滑动达到内层Tabs的边界处时,触发回调返回屏蔽使外层Tabs产生滑动手势。
673
674```ts
675// xxx.ets
676@Entry
677@Component
678struct Index {
679  @State currentIndex: number = 0
680  @State selectedIndex: number = 0
681  @State fontColor: string = '#182431'
682  @State selectedFontColor: string = '#007DFF'
683  innerSelectedIndex: number = 0 // 记录内层Tabs的索引
684  controller?: TabsController = new TabsController();
685  @Builder
686  tabBuilder(index: number, name: string) {
687    Column() {
688      Text(name)
689        .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
690        .fontSize(16)
691        .fontWeight(this.selectedIndex === index ? 500 : 400)
692        .lineHeight(22)
693        .margin({ top: 17, bottom: 7 })
694      Divider()
695        .strokeWidth(2)
696        .color('#007DFF')
697        .opacity(this.selectedIndex === index ? 1 : 0)
698    }.width('100%')
699  }
700  build() {
701    Column() {
702      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
703        TabContent() {
704          Column().width('100%').height('100%').backgroundColor(Color.Green)
705        }.tabBar(this.tabBuilder(0, 'green'))
706        TabContent() {
707          Tabs() {
708            TabContent() {
709              Column().width('100%').height('100%').backgroundColor(Color.Blue)
710            }.tabBar(new SubTabBarStyle('blue'))
711            TabContent() {
712              Column().width('100%').height('100%').backgroundColor(Color.Pink)
713            }.tabBar(new SubTabBarStyle('pink'))
714          }
715          .onAnimationStart((index: number, targetIndex: number) => {
716            console.info('ets onGestureRecognizerJudgeBegin child:' + targetIndex)
717            this.innerSelectedIndex = targetIndex
718          })
719          .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer,
720            others: Array<GestureRecognizer>): GestureJudgeResult => { // 在识别器即将要成功时,根据当前组件状态,设置识别器使能状态
721            console.info('ets onGestureRecognizerJudgeBegin child')
722            if (current) {
723              let target = current.getEventTargetInfo();
724              if (target && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) {
725                console.info('ets onGestureRecognizerJudgeBegin child PAN_GESTURE')
726                let panEvent = event as PanGestureEvent;
727                if (panEvent && panEvent.velocityX < 0 && this.innerSelectedIndex === 1) { // 内层Tabs滑动到尽头
728                  console.info('ets onGestureRecognizerJudgeBegin child reject end')
729                  return GestureJudgeResult.REJECT;
730                }
731                if (panEvent && panEvent.velocityX > 0 && this.innerSelectedIndex === 0) { // 内层Tabs滑动到开头
732                  console.info('ets onGestureRecognizerJudgeBegin child reject begin')
733                  return GestureJudgeResult.REJECT;
734                }
735              }
736            }
737            return GestureJudgeResult.CONTINUE;
738          }, true)
739        }.tabBar(this.tabBuilder(1, 'blue and pink'))
740        TabContent() {
741          Column().width('100%').height('100%').backgroundColor(Color.Brown)
742        }.tabBar(this.tabBuilder(2, 'brown'))
743      }
744      .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
745        // 切换动画开始时触发该回调。目标页签显示下划线。
746        this.selectedIndex = targetIndex
747      })
748    }
749  }
750}
751```
752
753 ![example](figures/gesture_recognizer.gif)
754
755
756### 示例3(拦截手势获取属性)
757
758该示例通过配置onGestureRecognizerJudgeBegin判定手势,获取相应属性参数。
759
760```ts
761// xxx.ets
762@Entry
763@Component
764struct Index {
765  @State message: string = 'Gesture';
766
767  build() {
768    Column() {
769      Row({ space: 20 }) {
770        Text(this.message)
771          .width(400)
772          .height(80)
773          .fontSize(23)
774      }.margin(25)
775    }
776    .margin(50)
777    .width(400)
778    .height(200)
779    .borderWidth(2)
780    .gesture(TapGesture())
781    .gesture(LongPressGesture())
782    .gesture(PanGesture({ direction: PanDirection.Vertical }))
783    .gesture(PinchGesture())
784    .gesture(RotationGesture())
785    .gesture(SwipeGesture({ direction: SwipeDirection.Horizontal }))
786    //通过给组件绑定自定义手势识别器判定回调
787    .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer,
788      others: Array<GestureRecognizer>) => {
789      if (current) {
790        //判断是否为拖动手势
791        if (current.getType() == GestureControl.GestureType.PAN_GESTURE) {
792          let target = current as PanRecognizer;
793          this.message = 'PanGesture\ndistance:' + target.getPanGestureOptions().getDistance() + '\nfingers:' +
794          target.getFingerCount() + '\nisFingerCountLimited:' + target.isFingerCountLimit();
795        }
796        //判断是否为长按手势
797        if (current.getType() == GestureControl.GestureType.LONG_PRESS_GESTURE) {
798          let target = current as LongPressRecognizer;
799          this.message = 'LongPressGesture\nfingers:' + target.getFingerCount() + '\nisFingerCountLimited:' +
800          target.isFingerCountLimit() + '\nrepeat:' + target.isRepeat() + '\nduration:' + target.getDuration();
801        }
802        //判断是否为捏合手势
803        if (current.getType() == GestureControl.GestureType.PINCH_GESTURE) {
804          let target = current as PinchRecognizer;
805          this.message = 'PinchGesture\ndistance:' + target.getDistance() + '\nfingers:' +
806          target.getFingerCount() + '\nisFingerCountLimited:' + target.isFingerCountLimit();
807        }
808        //判断是否为点击手势
809        if (current.getType() == GestureControl.GestureType.TAP_GESTURE) {
810          let target = current as TapRecognizer;
811          this.message = 'TapGesture\ncount:' + target.getTapCount() + '\nfingers:' +
812          target.getFingerCount() + '\nisFingerCountLimited:' + target.isFingerCountLimit();
813        }
814        //判断是否为旋转手势
815        if (current.getType() == GestureControl.GestureType.ROTATION_GESTURE) {
816          let target = current as RotationRecognizer;
817          this.message = 'RotationGesture\nangle:' + target.getAngle() + '\nfingers:' +
818          target.getFingerCount() + '\nisFingerCountLimited:' + target.isFingerCountLimit();
819        }
820        //判断是否为滑动手势
821        if (current.getType() == GestureControl.GestureType.SWIPE_GESTURE) {
822          let target = current as SwipeRecognizer;
823          this.message = 'SwipeGesture\ndirection:' + target.getDirection() + '\nfingers:' +
824          target.getFingerCount() + '\nisFingerCountLimited:' + target.isFingerCountLimit() + '\nspeed:' +
825          target.getVelocityThreshold();
826        }
827      }
828      return GestureJudgeResult.CONTINUE;
829    })
830  }
831}
832```
833
834 ![example](figures/gesture_recognizer_obtain_attributes.gif)