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## TouchTestInfo 38 39Provides information about the coordinate system, ID, and size of the component where the current touch point is located. 40 41**Atomic service API**: This API can be used in atomic services since API version 12. 42 43**System capability**: SystemCapability.ArkUI.ArkUI.Full 44 45| Name | Type | Description | 46| ------------- | ------ | ---------------------------------------- | 47| windowX | number | X coordinate of the touch point relative to the upper left corner of the window.| 48| windowY | number |Y coordinate of the touch point relative to the upper left corner of the window.| 49| parentX | number |X coordinate of the touch point relative to the upper left corner of the parent component. | 50| parentY | number |Y coordinate of the touch point relative to the upper left corner of the parent component. | 51| x | number | X coordinate of the touch point relative to the upper left corner of the child component.| 52| y | number | Y coordinate of the touch point relative to the upper left corner of the child component.| 53| rect | [RectResult](ts-types.md#rectresult10) |Size of the child component. | 54| [id](ts-universal-attributes-component-id.md) | string | Component ID.| 55 56## TouchResult 57 58Defines the custom event dispatch result. You can influence event dispatch by returning specific results. 59 60**Atomic service API**: This API can be used in atomic services since API version 12. 61 62**System capability**: SystemCapability.ArkUI.ArkUI.Full 63 64| Name | Type | Mandatory | Description | 65| --------- | --------- | ---- |--------------------------------------- | 66| strategy | [TouchTestStrategy](#touchteststrategy) | Yes | Event dispatch strategy. | 67| 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.| 68 69## TouchTestStrategy 70 71Describes the event dispatch strategy. 72 73**Widget capability**: This API can be used in ArkTS widgets since API version 11. 74 75**Atomic service API**: This API can be used in atomic services since API version 12. 76 77**System capability**: SystemCapability.ArkUI.ArkUI.Full 78 79| Name | Description | 80| ------------| ----------------------------------------- | 81| DEFAULT | Custom dispatch has no effect; the system distributes events based on the hit status of the current node.| 82| FORWARD_COMPETITION | The specified event is forwarded to a particular child node, and the system determines whether to distribute the event to other sibling nodes.| 83| FORWARD | The specified event is forwarded to a particular child node, and the system no longer distributes the event to other sibling nodes.| 84 85## Example 86 87### Example 1 88 89```ts 90// xxx.ets 91import { promptAction } from '@kit.ArkUI'; 92 93@Entry 94@Component 95struct ListExample { 96 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 97 @State text: string = 'Button' 98 99 build() { 100 Column() { 101 List({ space: 12, initialIndex: 0 }) { 102 ForEach(this.arr, (item: number) => { 103 ListItem() { 104 Text('Item ' + item) 105 .width('100%') 106 .height(56) 107 .fontSize(16) 108 .textAlign(TextAlign.Start) 109 }.borderRadius(24) 110 .backgroundColor(Color.White) 111 .padding({ left: 12, right: 12 }) 112 }, (item: string) => item) 113 } 114 .listDirection(Axis.Vertical) 115 .scrollBar(BarState.Off) 116 .edgeEffect(EdgeEffect.Spring) 117 .onScrollIndex((start: number, end: number) => { 118 console.info('first' + start) 119 console.info('last' + end) 120 }) 121 .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { 122 console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 123 }) 124 .width('100%') 125 .height('65%') 126 .id('MyList') 127 128 Button(this.text) 129 .width(312) 130 .height(40) 131 .id('Mybutton') 132 .fontSize(16) 133 .fontWeight(FontWeight.Medium) 134 .margin({ top: 80 }) 135 .onClick(() => { 136 this.text = 'click the button' 137 promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 138 }) 139 } 140 .width('100%') 141 .height('100%') 142 .backgroundColor(0xF1F3F5) 143 .justifyContent(FlexAlign.End) 144 .padding({ left: 12, right: 12, bottom: 24 }) 145 .onChildTouchTest((touchinfo) => { 146 for (let info of touchinfo) { 147 if (info.id == 'MyList') { 148 return { id: info.id, strategy: TouchTestStrategy.FORWARD_COMPETITION } 149 } 150 } 151 return { strategy: TouchTestStrategy.DEFAULT } 152 }) 153 } 154} 155``` 156After you touch the blank area in the lower part of the list and start dragging, the list scrolls. After you touch the button, the **onClick** event is triggered. 157 158 159 160### Example 2 161 162```ts 163// xxx.ets 164import { promptAction } from '@kit.ArkUI'; 165 166@Entry 167@Component 168struct ListExample { 169 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 170 @State text: string = 'Button' 171 172 build() { 173 Column() { 174 List({ space: 12, initialIndex: 0 }) { 175 ForEach(this.arr, (item: number) => { 176 ListItem() { 177 Text('Item ' + item) 178 .width('100%') 179 .height(56) 180 .fontSize(16) 181 .textAlign(TextAlign.Start) 182 }.borderRadius(24) 183 .backgroundColor(Color.White) 184 .padding({ left: 12, right: 12 }) 185 }, (item: string) => item) 186 } 187 .listDirection(Axis.Vertical) 188 .scrollBar(BarState.Off) 189 .edgeEffect(EdgeEffect.Spring) 190 .onScrollIndex((start: number, end: number) => { 191 console.info('first' + start) 192 console.info('last' + end) 193 }) 194 .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { 195 console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 196 }) 197 .width('100%') 198 .height('65%') 199 .id('MyList') 200 201 Button(this.text) 202 .width(312) 203 .height(40) 204 .id('Mybutton') 205 .fontSize(16) 206 .fontWeight(FontWeight.Medium) 207 .margin({ top: 80 }) 208 .onClick(() => { 209 this.text = 'click the button' 210 promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 211 }) 212 } 213 .width('100%') 214 .height('100%') 215 .backgroundColor(0xF1F3F5) 216 .justifyContent(FlexAlign.End) 217 .padding({ left: 12, right: 12, bottom: 24 }) 218 .onChildTouchTest((touchinfo) => { 219 for (let info of touchinfo) { 220 if (info.id == 'MyList') { 221 return { id: info.id, strategy: TouchTestStrategy.FORWARD } 222 } 223 } 224 return { strategy: TouchTestStrategy.DEFAULT } 225 }) 226 } 227} 228``` 229After you touch the blank area in the lower part of the list and start dragging, the list scrolls. After you touch the button, the **onClick** event is not triggered. 230 231 232 233### Example 3 234 235```ts 236// xxx.ets 237import { promptAction } from '@kit.ArkUI'; 238 239@Entry 240@Component 241struct ListExample { 242 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 243 @State text: string = 'Button' 244 245 build() { 246 Column() { 247 List({ space: 12, initialIndex: 0 }) { 248 ForEach(this.arr, (item: number) => { 249 ListItem() { 250 Text('Item ' + item) 251 .width('100%') 252 .height(56) 253 .fontSize(16) 254 .textAlign(TextAlign.Start) 255 }.borderRadius(24) 256 .backgroundColor(Color.White) 257 .padding({ left: 12, right: 12 }) 258 }, (item: string) => item) 259 } 260 .listDirection(Axis.Vertical) 261 .scrollBar(BarState.Off) 262 .edgeEffect(EdgeEffect.Spring) 263 .onScrollIndex((start: number, end: number) => { 264 console.info('first' + start) 265 console.info('last' + end) 266 }) 267 .onDidScroll((scrollOffset: number, scrollState: ScrollState) => { 268 console.info(`onScroll scrollState = ScrollState` + scrollState + `, scrollOffset = ` + scrollOffset) 269 }) 270 .width('100%') 271 .height('65%') 272 .id('MyList') 273 274 Button(this.text) 275 .width(312) 276 .height(40) 277 .id('Mybutton') 278 .fontSize(16) 279 .fontWeight(FontWeight.Medium) 280 .margin({ top: 80 }) 281 .onClick(() => { 282 this.text = 'click the button' 283 promptAction.showToast({ message: 'you click the button.', duration: 3000 }) 284 }) 285 } 286 .width('100%') 287 .height('100%') 288 .backgroundColor(0xF1F3F5) 289 .justifyContent(FlexAlign.End) 290 .padding({ left: 12, right: 12, bottom: 24 }) 291 .onChildTouchTest((touchinfo) => { 292 return { strategy: TouchTestStrategy.DEFAULT } 293 }) 294 } 295} 296``` 297After you touch the blank area in the lower part of the list and start dragging, the list does not scroll. After you touch the button, the **onClick** event is triggered. 298 299 300