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  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 