1# Gesture Blocking Enhancement 2 3Gesture blocking enhancement offers components the capability to block gestures. You can handle built-in gestures in parallel with gestures that have a higher priority as needed, and can dynamically control the triggering of gesture events. 4 5> **NOTE** 6> 7> The initial APIs of this module are supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version. 8 9## shouldBuiltInRecognizerParallelWith 10shouldBuiltInRecognizerParallelWith(callback: ShouldBuiltInRecognizerParallelWithCallback): T 11 12**Parameters** 13| Name | Type | Mandatory | Description | 14| ---------- | -------------------------- | ------- | ----------------------------- | 15| callback | [ShouldBuiltInRecognizerParallelWithCallback](#shouldbuiltinrecognizerparallelwithcallback) | Yes | Callback used to set the parallel relationship between the system's built-in gestures and the gestures of other components within the response chain. When the current component undergoes touch collision detection, a custom callback is triggered to establish the gesture parallel relationship.| 16 17**Return value** 18 19| Type| Description| 20| -------- | -------- | 21| T | Current component.| 22 23## ShouldBuiltInRecognizerParallelWithCallback 24 25type ShouldBuiltInRecognizerParallelWithCallback = (current: GestureRecognizer, others: Array\<GestureRecognizer\>) => GestureRecognizer 26 27Represents the callback used to set the parallel relationship between the system's built-in gestures and the gestures of other components within the response chain. 28 29**Atomic service API**: This API can be used in atomic services since API version 12. 30 31**System capability**: SystemCapability.ArkUI.ArkUI.Full 32 33**Parameters** 34 35| Name | Type | Mandatory| Description | 36| -------- | ------------------------- | ---- | ------------------------------------------------------------ | 37| current | [GestureRecognizer](#gesturerecognizer) | Yes | Built-in gesture recognizer of the current component. Currently only a built-in gesture recognizer of the [PAN_GESTURE](ts-gesture-customize-judge.md#gesturejudgeresult11) type is supported.| 38| others | Array\<[GestureRecognizer](#gesturerecognizer)\> | Yes | Other gesture recognizers of the same category from components with higher priority in the response chain.| 39 40**Return value** 41 42| Type | Description | 43| ------ | --------- | 44| [GestureRecognizer](#gesturerecognizer) | Gesture recognizer that is bound in parallel with the current recognizer.| 45 46## GestureRecognizer 47 48Defines a gesture recognizer object. 49 50### getTag 51 52getTag(): string 53 54Obtains the tag of this gesture recognizer. 55 56**Atomic service API**: This API can be used in atomic services since API version 12. 57 58**Return value** 59 60| Type | Description | 61| ------ | --------- | 62| string | Tag of the current gesture recognizer.| 63 64### getType 65 66getType(): GestureControl.GestureType 67 68Obtains the type of this gesture recognizer. 69 70**Atomic service API**: This API can be used in atomic services since API version 12. 71 72**Return value** 73 74| Type | Description | 75| ------ | --------- | 76| [GestureControl.GestureType](ts-gesture-customize-judge.md#gesturetype11) | Type of the current gesture recognizer.| 77 78### isBuiltIn 79 80isBuiltIn(): boolean 81 82Obtains whether this gesture recognizer is a built-in gesture. 83 84**Atomic service API**: This API can be used in atomic services since API version 12. 85 86**Return value** 87 88| Type | Description | 89| ------ | --------- | 90| boolean | Whether this gesture recognizer is a built-in gesture.| 91 92### setEnabled 93 94setEnabled(isEnabled: boolean): void 95 96Sets the enabled state of this gesture recognizer. 97 98**Atomic service API**: This API can be used in atomic services since API version 12. 99 100**Parameters** 101 102| Name | Type | Mandatory | Description | 103| ------- | ---------------------------------- | ---- | ----- | 104| isEnabled | boolean | Yes | Enabled state to set.| 105 106### isEnabled 107 108isEnabled(): boolean 109 110Obtains the enabled state of this gesture recognizer. 111 112**Atomic service API**: This API can be used in atomic services since API version 12. 113 114**Return value** 115 116| Type | Description | 117| ------ | --------- | 118| boolean | Enabled state of the gesture recognizer.| 119 120### getState 121 122getState(): GestureRecognizerState 123 124Obtains the state of this gesture recognizer. 125 126**Atomic service API**: This API can be used in atomic services since API version 12. 127 128**Return value** 129 130| Type | Description | 131| ------ | --------- | 132| [GestureRecognizerState](#gesturerecognizerstate) | State of the gesture recognizer.| 133 134### getEventTargetInfo 135 136getEventTargetInfo(): EventTargetInfo 137 138Obtains the information about the component corresponding to this gesture recognizer. 139 140**Atomic service API**: This API can be used in atomic services since API version 12. 141 142**Return value** 143 144| Type | Description | 145| ------ | --------- | 146| [EventTargetInfo](#eventtargetinfo) | Information about the component corresponding to the current gesture recognizer.| 147 148## GestureRecognizerState 149 150Enumerates the gesture recognizer states. 151 152**Atomic service API**: This API can be used in atomic services since API version 12. 153 154| Name | Value | Description | 155| ------- | ---- | ---------------------------------- | 156| READY | 0 | Ready.| 157| DETECTING | 1 | Detecting.| 158| PENDING | 2 | Pending.| 159| BLOCKED | 3 | Blocked.| 160| SUCCESSFUL | 4 | Successful.| 161| FAILED | 5 | Failed.| 162 163## EventTargetInfo 164 165Provides the information about the component corresponding to the gesture recognizer. 166 167### getId 168 169getId(): string 170 171Obtains the ID of this component. 172 173**Atomic service API**: This API can be used in atomic services since API version 12. 174 175**Return value** 176 177| Type | Description | 178| ------ | --------- | 179| string | [ID](./ts-universal-attributes-component-id.md#id) of the current component.| 180 181## ScrollableTargetInfo 182 183Provides the information about the scroll container component corresponding to the gesture recognizer. It inherits from [EventTargetInfo](#eventtargetinfo). 184 185### isBegin 186 187isBegin(): boolean 188 189Checks whether this scroll container is scrolled to the top. If the container is a **Swiper** component and is in loop mode, **false** is returned. 190 191**Atomic service API**: This API can be used in atomic services since API version 12. 192 193**Return value** 194 195| Type | Description | 196| ------ | --------- | 197| boolean | Whether the current scroll container is scrolled to the top.| 198 199### isEnd 200 201isEnd(): boolean 202 203Checks whether this scroll container is scrolled to the bottom. If the container is a **Swiper** component and is in loop mode, **false** is returned. 204 205**Atomic service API**: This API can be used in atomic services since API version 12. 206 207**Return value** 208 209| Type | Description | 210| ------ | --------- | 211| boolean | Whether the scroll container is scrolled to the bottom.| 212 213## PanRecognizer 214 215Defines a pan gesture recognizer object. It inherits from [GestureRecognizer](#gesturerecognizer). 216 217### getPanGestureOptions 218 219getPanGestureOptions(): PanGestureOptions 220 221Obtains the properties of this pan gesture recognizer. 222 223**Atomic service API**: This API can be used in atomic services since API version 12. 224 225**Return value** 226 227| Type | Description | 228| ------ | --------- | 229| [PanGestureOptions](./ts-basic-gestures-pangesture.md#pangestureoptions) | Properties of the current pan gesture recognizer.| 230 231## onGestureRecognizerJudgeBegin 232 233onGestureRecognizerJudgeBegin(callback: GestureRecognizerJudgeBeginCallback): T 234 235**Parameters** 236| Name | Type | Mandatory | Description | 237| ---------- | -------------------------- | ------- | ----------------------------- | 238| callback | [GestureRecognizerJudgeBeginCallback](#gesturerecognizerjudgebegincallback) | Yes | Custom gesture recognizer judgment callback to bind to the component. When the gesture bound to the current component is accepted, a custom callback is triggered to obtain the result.| 239 240**Return value** 241 242| Type| Description| 243| -------- | -------- | 244| T | Current component.| 245 246## GestureRecognizerJudgeBeginCallback 247 248type GestureRecognizerJudgeBeginCallback = (event: BaseGestureEvent, current: GestureRecognizer, recognizers: Array\<GestureRecognizer\>) => GestureJudgeResult 249 250Represents a custom gesture recognizer judgment callback. 251 252**Atomic service API**: This API can be used in atomic services since API version 12. 253 254**System capability**: SystemCapability.ArkUI.ArkUI.Full 255 256**Parameters** 257 258| Name | Type | Mandatory| Description | 259| -------- | ------------------------- | ---- | ------------------------------------------------------------ | 260| event | [BaseGestureEvent](./ts-gesture-customize-judge.md#basegestureevent) | Yes | Information about the current basic gesture event.| 261| current | [GestureRecognizer](#gesturerecognizer) | Yes | Gesture recognizer object that is about to respond.| 262| others | Array\<[GestureRecognizer](#gesturerecognizer)\> | Yes | Other gesture recognizer objects in the response chain.| 263 264**Return value** 265 266| Type | Description | 267| ------ | --------- | 268| [GestureJudgeResult](ts-gesture-customize-judge.md#gesturejudgeresult11) | Result of whether the gesture judgment is successful.| 269 270## Example 271 272```ts 273// xxx.ets 274@Entry 275@Component 276struct FatherControlChild { 277 scroller: Scroller = new Scroller() 278 scroller2: Scroller = new Scroller() 279 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 280 private childRecognizer: GestureRecognizer = new GestureRecognizer() 281 private currentRecognizer: GestureRecognizer = new GestureRecognizer() 282 private lastOffset: number = 0 283 284 build() { 285 Stack({ alignContent: Alignment.TopStart }) { 286 Scroll(this.scroller) { // External scroll container. 287 Column() { 288 Text("Scroll Area") 289 .width('90%') 290 .height(150) 291 .backgroundColor(0xFFFFFF) 292 .borderRadius(15) 293 .fontSize(16) 294 .textAlign(TextAlign.Center) 295 .margin({ top: 10 }) 296 Scroll(this.scroller2) { // Internal scroll container. 297 Column() { 298 Text("Scroll Area2") 299 .width('90%') 300 .height(150) 301 .backgroundColor(0xFFFFFF) 302 .borderRadius(15) 303 .fontSize(16) 304 .textAlign(TextAlign.Center) 305 .margin({ top: 10 }) 306 Column() { 307 ForEach(this.arr, (item: number) => { 308 Text(item.toString()) 309 .width('90%') 310 .height(150) 311 .backgroundColor(0xFFFFFF) 312 .borderRadius(15) 313 .fontSize(16) 314 .textAlign(TextAlign.Center) 315 .margin({ top: 10 }) 316 }, (item: string) => item) 317 }.width('100%') 318 } 319 } 320 .id("inner") 321 .width('100%') 322 .height(800) 323 }.width('100%') 324 } 325 .id("outer") 326 .height(600) 327 .scrollable(ScrollDirection.Vertical) // The scrollbar scrolls in the vertical direction. 328 .scrollBar(BarState.On) // The scrollbar is always displayed. 329 .scrollBarColor(Color.Gray) // The scrollbar color is gray. 330 .scrollBarWidth(10) // The scrollbar width is 10. 331 .edgeEffect(EdgeEffect.None) 332 .shouldBuiltInRecognizerParallelWith((current: GestureRecognizer, others: Array<GestureRecognizer>) => { 333 for (let i = 0; i < others.length; i++) { 334 let target = others[i].getEventTargetInfo(); 335 if (target) { 336 if (target.getId() == "inner" && others[i].isBuiltIn() && others[i].getType() == GestureControl.GestureType.PAN_GESTURE) { // Find the recognizer that will form the parallel gesture recognition. 337 this.currentRecognizer = current; // Save the recognizer of the current component. 338 this.childRecognizer = others[i]; // Save the recognizer that will form the parallel gesture recognition. 339 return others[i]; // Return the recognizer that will form the parallel gesture recognition. 340 } 341 } 342 } 343 return undefined; 344 }) 345 .onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, others: Array<GestureRecognizer>) => { // When the recognizer is about to succeed, set the enabled state of the recognizer based on the current component state. 346 if (current) { 347 let target = current.getEventTargetInfo(); 348 if (target) { 349 if (target.getId() == "outer" && current.isBuiltIn() && current.getType() == GestureControl.GestureType.PAN_GESTURE) { 350 if (others) { 351 for (let i = 0; i < others.length; i++) { 352 let target = others[i].getEventTargetInfo() as ScrollableTargetInfo; 353 if (target instanceof ScrollableTargetInfo && target.getId() == "inner") { // Find the corresponding parallel recognizer in the response chain. 354 let panEvent = event as PanGestureEvent; 355 if (target.isEnd()) {// Dynamically control the enabled state of the recognizer based on the current component state and movement direction. 356 if (panEvent && panEvent.offsetY < 0) { 357 this.childRecognizer.setEnabled(false) 358 this.currentRecognizer.setEnabled(true) 359 } else { 360 this.childRecognizer.setEnabled(true) 361 this.currentRecognizer.setEnabled(false) 362 } 363 } else if (target.isBegin()) { 364 if (panEvent.offsetY > 0) { 365 this.childRecognizer.setEnabled(false) 366 this.currentRecognizer.setEnabled(true) 367 } else { 368 this.childRecognizer.setEnabled(true) 369 this.currentRecognizer.setEnabled(false) 370 } 371 } else { 372 this.childRecognizer.setEnabled(true) 373 this.currentRecognizer.setEnabled(false) 374 } 375 } 376 } 377 } 378 } 379 } 380 } 381 return GestureJudgeResult.CONTINUE; 382 }) 383 .parallelGesture( // Bind a pan gesture as a dynamic controller. 384 PanGesture() 385 .onActionUpdate((event: GestureEvent)=>{ 386 if (this.childRecognizer.getState() != GestureRecognizerState.SUCCESSFUL || this.currentRecognizer.getState() != GestureRecognizerState.SUCCESSFUL) { // If the recognizer's state is not SUCCESSFUL, do not perform control. 387 return; 388 } 389 let target = this.childRecognizer.getEventTargetInfo() as ScrollableTargetInfo; 390 let currentTarget = this.currentRecognizer.getEventTargetInfo() as ScrollableTargetInfo; 391 if (target instanceof ScrollableTargetInfo && currentTarget instanceof ScrollableTargetInfo) { 392 if (target.isEnd()) { // Based on the component state during the movement, control the enabled state of the recognizer. 393 if ((event.offsetY - this.lastOffset) < 0) { 394 this.childRecognizer.setEnabled(false) 395 if (currentTarget.isEnd()) { 396 this.currentRecognizer.setEnabled(false) 397 } else { 398 this.currentRecognizer.setEnabled(true) 399 } 400 } else { 401 this.childRecognizer.setEnabled(true) 402 this.currentRecognizer.setEnabled(false) 403 } 404 } else if (target.isBegin()) { 405 if ((event.offsetY - this.lastOffset) > 0) { 406 this.childRecognizer.setEnabled(false) 407 if (currentTarget.isBegin()) { 408 this.currentRecognizer.setEnabled(false) 409 } else { 410 this.currentRecognizer.setEnabled(true) 411 } 412 } else { 413 this.childRecognizer.setEnabled(true) 414 this.currentRecognizer.setEnabled(false) 415 } 416 } else { 417 this.childRecognizer.setEnabled(true) 418 this.currentRecognizer.setEnabled(false) 419 } 420 } 421 this.lastOffset = event.offsetY 422 }) 423 ) 424 }.width('100%').height('100%').backgroundColor(0xDCDCDC) 425 } 426} 427``` 428