1e41f4b71Sopenharmony_ci# Custom Event Dispatch 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciWhen handling a touch event, ArkUI performs a touch test on the touch point and the component area before the event is triggered – to determine the components targeted by the event – and dispatches the event based on the test result. You can use **onChildTouchTest** on a parent node to specify how to perform the touch test on child nodes and thereby exert an impact on touch event dispatch. For details about the impact, see [TouchTestStrategy](#touchteststrategy). 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci> **NOTE** 6e41f4b71Sopenharmony_ci> 7e41f4b71Sopenharmony_ci> - This feature is supported since API version 11. Updates will be marked with a superscript to indicate their earliest API version. 8e41f4b71Sopenharmony_ci> 9e41f4b71Sopenharmony_ci> - With use of **onChildTouchTest**, the **onClick**, rotation, and pinch gesture events may receive no response due to the touch target not being hit. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci## onChildTouchTest 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_cionChildTouchTest(event: (value: Array<TouchTestInfo>) => TouchResult): T 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ciCalled to specify how to perform the touch test on the children of this component. 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci**Parameters** 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci| Name| Type | Mandatory| Description | 24e41f4b71Sopenharmony_ci| ------ | ------------------------------------------ | ---- | ---------------------- | 25e41f4b71Sopenharmony_ci| value | Array<[TouchTestInfo>](#touchtestinfo) | Yes | Array of child components.| 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci**Return value** 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci| Type| Description| 30e41f4b71Sopenharmony_ci| -------- | -------- | 31e41f4b71Sopenharmony_ci| T | Current component.| 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci>**NOTE** 34e41f4b71Sopenharmony_ci> 35e41f4b71Sopenharmony_ci>The array of child components contains only components for which **id** is set. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci## TouchTestInfo 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 41e41f4b71Sopenharmony_ci 42e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 43e41f4b71Sopenharmony_ci 44e41f4b71Sopenharmony_ci| Name | Type | Description | 45e41f4b71Sopenharmony_ci| ------------- | ------ | ---------------------------------------- | 46e41f4b71Sopenharmony_ci| windowX | number | X coordinate of the touch point relative to the upper left corner of the window.| 47e41f4b71Sopenharmony_ci| windowY | number |Y coordinate of the touch point relative to the upper left corner of the window.| 48e41f4b71Sopenharmony_ci| parentX | number |X coordinate of the touch point relative to the upper left corner of the parent component. | 49e41f4b71Sopenharmony_ci| parentY | number |Y coordinate of the touch point relative to the upper left corner of the parent component. | 50e41f4b71Sopenharmony_ci| x | number | X coordinate of the touch point relative to the upper left corner of the child component.| 51e41f4b71Sopenharmony_ci| y | number | Y coordinate of the touch point relative to the upper left corner of the child component.| 52e41f4b71Sopenharmony_ci| rect | [RectResult](ts-types.md#rectresult10) |Size of the child component. | 53e41f4b71Sopenharmony_ci| [id](ts-universal-attributes-component-id.md) | string | Component ID.| 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci## TouchResult 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci| Name | Type | Mandatory | Description | 62e41f4b71Sopenharmony_ci| --------- | --------- | ---- |--------------------------------------- | 63e41f4b71Sopenharmony_ci| strategy | [TouchTestStrategy](#touchteststrategy) | Yes | Event dispatch strategy. | 64e41f4b71Sopenharmony_ci| id | string | No | Component ID.<br>If **strategy** is set to **TouchTestStrategy.DEFAULT**, **id** is optional. If **strategy** is set to **TouchTestStrategy.FORWARD_COMPETITION** or **TouchTestStrategy.FORWARD**, **id** is mandatory. If **id** is not returned, the strategy **TouchTestStrategy.DEFAULT** is used.| 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci## TouchTestStrategy 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci**Widget capability**: This API can be used in ArkTS widgets since API version 11. 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci**Atomic service API**: This API can be used in atomic services since API version 12. 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci**System capability**: SystemCapability.ArkUI.ArkUI.Full 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci| Name | Description | 75e41f4b71Sopenharmony_ci| ------------| ----------------------------------------- | 76e41f4b71Sopenharmony_ci| DEFAULT | The default event dispatch mechanism for components is used.| 77e41f4b71Sopenharmony_ci| FORWARD_COMPETITION | The event is dispatched to the specified child component, while the ArkUI touch test process is followed.| 78e41f4b71Sopenharmony_ci| FORWARD | The event is dispatched to the specified child component, and the ArkUI touch test process is not followed.| 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci## Example 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci### Example 1 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci```ts 85e41f4b71Sopenharmony_ci// xxx.ets 86e41f4b71Sopenharmony_ciimport { promptAction } from '@kit.ArkUI'; 87e41f4b71Sopenharmony_ci 88e41f4b71Sopenharmony_ci@Entry 89e41f4b71Sopenharmony_ci@Component 90e41f4b71Sopenharmony_cistruct ListExample { 91e41f4b71Sopenharmony_ci private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 92e41f4b71Sopenharmony_ci @State text: string = 'Button' 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci build() { 95e41f4b71Sopenharmony_ci Column() { 96e41f4b71Sopenharmony_ci List({ space: 12, initialIndex: 0 }) { 97e41f4b71Sopenharmony_ci ForEach(this.arr, (item: number) => { 98e41f4b71Sopenharmony_ci ListItem() { 99e41f4b71Sopenharmony_ci Text('Item ' + item) 100e41f4b71Sopenharmony_ci .width('100%') 101e41f4b71Sopenharmony_ci .height(56) 102e41f4b71Sopenharmony_ci .fontSize(16) 103e41f4b71Sopenharmony_ci .textAlign(TextAlign.Start) 104e41f4b71Sopenharmony_ci }.borderRadius(24) 105e41f4b71Sopenharmony_ci .backgroundColor(Color.White) 106e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12 }) 107e41f4b71Sopenharmony_ci }, (item: string) => item) 108e41f4b71Sopenharmony_ci } 109e41f4b71Sopenharmony_ci .listDirection(Axis.Vertical) 110e41f4b71Sopenharmony_ci .scrollBar(BarState.Off) 111e41f4b71Sopenharmony_ci .edgeEffect(EdgeEffect.Spring) 112e41f4b71Sopenharmony_ci .onScrollIndex((start: number, end: number) => { 113e41f4b71Sopenharmony_ci console.info('first' + start) 114e41f4b71Sopenharmony_ci console.info('last' + end) 115e41f4b71Sopenharmony_ci }) 116e41f4b71Sopenharmony_ci .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { 117e41f4b71Sopenharmony_ci console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 118e41f4b71Sopenharmony_ci }) 119e41f4b71Sopenharmony_ci .width('100%') 120e41f4b71Sopenharmony_ci .height('65%') 121e41f4b71Sopenharmony_ci .id('MyList') 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci Button(this.text) 124e41f4b71Sopenharmony_ci .width(312) 125e41f4b71Sopenharmony_ci .height(40) 126e41f4b71Sopenharmony_ci .id('Mybutton') 127e41f4b71Sopenharmony_ci .fontSize(16) 128e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Medium) 129e41f4b71Sopenharmony_ci .margin({ top: 80 }) 130e41f4b71Sopenharmony_ci .onClick(() => { 131e41f4b71Sopenharmony_ci this.text = 'click the button' 132e41f4b71Sopenharmony_ci promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 133e41f4b71Sopenharmony_ci }) 134e41f4b71Sopenharmony_ci } 135e41f4b71Sopenharmony_ci .width('100%') 136e41f4b71Sopenharmony_ci .height('100%') 137e41f4b71Sopenharmony_ci .backgroundColor(0xF1F3F5) 138e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.End) 139e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12, bottom: 24 }) 140e41f4b71Sopenharmony_ci .onChildTouchTest((touchinfo) => { 141e41f4b71Sopenharmony_ci for (let info of touchinfo) { 142e41f4b71Sopenharmony_ci if (info.id == 'MyList') { 143e41f4b71Sopenharmony_ci return { id: info.id, strategy: TouchTestStrategy.FORWARD_COMPETITION } 144e41f4b71Sopenharmony_ci } 145e41f4b71Sopenharmony_ci } 146e41f4b71Sopenharmony_ci return { strategy: TouchTestStrategy.DEFAULT } 147e41f4b71Sopenharmony_ci }) 148e41f4b71Sopenharmony_ci } 149e41f4b71Sopenharmony_ci} 150e41f4b71Sopenharmony_ci``` 151e41f4b71Sopenharmony_ciAfter you touch the blank area in the lower part and drag the list, the list scrolls. After you touch the button, the button responds to the **onClick** event. 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci 154e41f4b71Sopenharmony_ci 155e41f4b71Sopenharmony_ci### Example 2 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci```ts 158e41f4b71Sopenharmony_ci// xxx.ets 159e41f4b71Sopenharmony_ciimport { promptAction } from '@kit.ArkUI'; 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ci@Entry 162e41f4b71Sopenharmony_ci@Component 163e41f4b71Sopenharmony_cistruct ListExample { 164e41f4b71Sopenharmony_ci private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 165e41f4b71Sopenharmony_ci @State text: string = 'Button' 166e41f4b71Sopenharmony_ci 167e41f4b71Sopenharmony_ci build() { 168e41f4b71Sopenharmony_ci Column() { 169e41f4b71Sopenharmony_ci List({ space: 12, initialIndex: 0 }) { 170e41f4b71Sopenharmony_ci ForEach(this.arr, (item: number) => { 171e41f4b71Sopenharmony_ci ListItem() { 172e41f4b71Sopenharmony_ci Text('Item ' + item) 173e41f4b71Sopenharmony_ci .width('100%') 174e41f4b71Sopenharmony_ci .height(56) 175e41f4b71Sopenharmony_ci .fontSize(16) 176e41f4b71Sopenharmony_ci .textAlign(TextAlign.Start) 177e41f4b71Sopenharmony_ci }.borderRadius(24) 178e41f4b71Sopenharmony_ci .backgroundColor(Color.White) 179e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12 }) 180e41f4b71Sopenharmony_ci }, (item: string) => item) 181e41f4b71Sopenharmony_ci } 182e41f4b71Sopenharmony_ci .listDirection(Axis.Vertical) 183e41f4b71Sopenharmony_ci .scrollBar(BarState.Off) 184e41f4b71Sopenharmony_ci .edgeEffect(EdgeEffect.Spring) 185e41f4b71Sopenharmony_ci .onScrollIndex((start: number, end: number) => { 186e41f4b71Sopenharmony_ci console.info('first' + start) 187e41f4b71Sopenharmony_ci console.info('last' + end) 188e41f4b71Sopenharmony_ci }) 189e41f4b71Sopenharmony_ci .onScroll((scrollOffset: number, scrollState: ScrollState) => { 190e41f4b71Sopenharmony_ci console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 191e41f4b71Sopenharmony_ci }) 192e41f4b71Sopenharmony_ci .width('100%') 193e41f4b71Sopenharmony_ci .height('65%') 194e41f4b71Sopenharmony_ci .id('MyList') 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci Button(this.text) 197e41f4b71Sopenharmony_ci .width(312) 198e41f4b71Sopenharmony_ci .height(40) 199e41f4b71Sopenharmony_ci .id('Mybutton') 200e41f4b71Sopenharmony_ci .fontSize(16) 201e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Medium) 202e41f4b71Sopenharmony_ci .margin({ top: 80 }) 203e41f4b71Sopenharmony_ci .onClick(() => { 204e41f4b71Sopenharmony_ci this.text = 'click the button' 205e41f4b71Sopenharmony_ci promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 206e41f4b71Sopenharmony_ci }) 207e41f4b71Sopenharmony_ci } 208e41f4b71Sopenharmony_ci .width('100%') 209e41f4b71Sopenharmony_ci .height('100%') 210e41f4b71Sopenharmony_ci .backgroundColor(0xF1F3F5) 211e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.End) 212e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12, bottom: 24 }) 213e41f4b71Sopenharmony_ci .onChildTouchTest((touchinfo) => { 214e41f4b71Sopenharmony_ci for (let info of touchinfo) { 215e41f4b71Sopenharmony_ci if (info.id == 'MyList') { 216e41f4b71Sopenharmony_ci return { id: info.id, strategy: TouchTestStrategy.FORWARD } 217e41f4b71Sopenharmony_ci } 218e41f4b71Sopenharmony_ci } 219e41f4b71Sopenharmony_ci return { strategy: TouchTestStrategy.DEFAULT } 220e41f4b71Sopenharmony_ci }) 221e41f4b71Sopenharmony_ci } 222e41f4b71Sopenharmony_ci} 223e41f4b71Sopenharmony_ci``` 224e41f4b71Sopenharmony_ciAfter you touch the blank area in the lower part and drag the list, the list scrolls. After you touch the button, the button does not respond to the **onClick** event. 225e41f4b71Sopenharmony_ci 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ci### Example 3 229e41f4b71Sopenharmony_ci 230e41f4b71Sopenharmony_ci```ts 231e41f4b71Sopenharmony_ci// xxx.ets 232e41f4b71Sopenharmony_ciimport { promptAction } from '@kit.ArkUI'; 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci@Entry 235e41f4b71Sopenharmony_ci@Component 236e41f4b71Sopenharmony_cistruct ListExample { 237e41f4b71Sopenharmony_ci private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 238e41f4b71Sopenharmony_ci @State text: string = 'Button' 239e41f4b71Sopenharmony_ci 240e41f4b71Sopenharmony_ci build() { 241e41f4b71Sopenharmony_ci Column() { 242e41f4b71Sopenharmony_ci List({ space: 12, initialIndex: 0 }) { 243e41f4b71Sopenharmony_ci ForEach(this.arr, (item: number) => { 244e41f4b71Sopenharmony_ci ListItem() { 245e41f4b71Sopenharmony_ci Text('Item ' + item) 246e41f4b71Sopenharmony_ci .width('100%') 247e41f4b71Sopenharmony_ci .height(56) 248e41f4b71Sopenharmony_ci .fontSize(16) 249e41f4b71Sopenharmony_ci .textAlign(TextAlign.Start) 250e41f4b71Sopenharmony_ci }.borderRadius(24) 251e41f4b71Sopenharmony_ci .backgroundColor(Color.White) 252e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12 }) 253e41f4b71Sopenharmony_ci }, (item: string) => item) 254e41f4b71Sopenharmony_ci } 255e41f4b71Sopenharmony_ci .listDirection(Axis.Vertical) 256e41f4b71Sopenharmony_ci .scrollBar(BarState.Off) 257e41f4b71Sopenharmony_ci .edgeEffect(EdgeEffect.Spring) 258e41f4b71Sopenharmony_ci .onScrollIndex((start: number, end: number) => { 259e41f4b71Sopenharmony_ci console.info('first' + start) 260e41f4b71Sopenharmony_ci console.info('last' + end) 261e41f4b71Sopenharmony_ci }) 262e41f4b71Sopenharmony_ci .onScroll((scrollOffset: number, scrollState: ScrollState) => { 263e41f4b71Sopenharmony_ci console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 264e41f4b71Sopenharmony_ci }) 265e41f4b71Sopenharmony_ci .width('100%') 266e41f4b71Sopenharmony_ci .height('65%') 267e41f4b71Sopenharmony_ci .id('MyList') 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci Button(this.text) 270e41f4b71Sopenharmony_ci .width(312) 271e41f4b71Sopenharmony_ci .height(40) 272e41f4b71Sopenharmony_ci .id('Mybutton') 273e41f4b71Sopenharmony_ci .fontSize(16) 274e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Medium) 275e41f4b71Sopenharmony_ci .margin({ top: 80 }) 276e41f4b71Sopenharmony_ci .onClick(() => { 277e41f4b71Sopenharmony_ci this.text = 'click the button' 278e41f4b71Sopenharmony_ci promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 279e41f4b71Sopenharmony_ci }) 280e41f4b71Sopenharmony_ci } 281e41f4b71Sopenharmony_ci .width('100%') 282e41f4b71Sopenharmony_ci .height('100%') 283e41f4b71Sopenharmony_ci .backgroundColor(0xF1F3F5) 284e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.End) 285e41f4b71Sopenharmony_ci .padding({ left: 12, right: 12, bottom: 24 }) 286e41f4b71Sopenharmony_ci .onChildTouchTest((touchinfo) => { 287e41f4b71Sopenharmony_ci return { strategy: TouchTestStrategy.DEFAULT } 288e41f4b71Sopenharmony_ci }) 289e41f4b71Sopenharmony_ci } 290e41f4b71Sopenharmony_ci} 291e41f4b71Sopenharmony_ci``` 292e41f4b71Sopenharmony_ciAfter you touch the blank area in the lower part and drag the list, the list does not scroll. After you touch the button, the button responds to the **onClick** event. 293e41f4b71Sopenharmony_ci 294e41f4b71Sopenharmony_ci 295