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