1# Drag Event 2 3A drag event is triggered when a component is dragged. 4 5> **NOTE** 6> 7> The APIs of this module are supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version. 8 9## Events 10 11| Name | Bubbling Supported| Description | 12| ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | 13| onDragStart(event: (event?: [DragEvent](#dragevent), extraParams?: string) => [CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](#dragiteminfo)) | No | Triggered when the component bound to the event is dragged for the first time.<br>- **event**: information about the drag event, including the coordinates of the item that is being dragged.<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.<br>Return value: object being dragged, which is used for prompts displayed when the object is dragged.<br>A drag event can be triggered by a 150 ms long press. If the duration of a long-press gesture is set to less than or equal to 150 ms, the callback for the long-press gesture takes precedence. Otherwise, the callback for the drag event takes precedence. | 14| onDragEnter(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item enters a valid drop target.<br>- **event**: information about the drag event, including the coordinates of the item that is being dragged.<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.<br>This event is valid only when a listener for the **onDrop** event is enabled.| 15| onDragMove(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item moves in a valid drop target.<br>- **event**: information about the drag event, including the coordinates of the item that is being dragged.<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.<br>This event is valid only when a listener for the **onDrop** event is enabled.| 16| onDragLeave(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item leaves a valid drop target.<br>- **event**: information about the drag event, including the coordinates of the item that is being dragged.<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.<br>This event is valid only when a listener for the **onDrop** event is enabled.| 17| onDrop(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void) | No | Triggered when the dragged item is dropped on a valid drop target.<br>- **event**: information about the drag event, including the coordinates of the item that is being dragged.<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.| 18 19## DragItemInfo 20 21| Name | Type | Mandatory | Description | 22| --------- | ---------------------------------------- | ---- | --------------------------------- | 23| pixelMap | [PixelMap](../apis/js-apis-image.md#pixelmap7) | No | Image to be displayed during dragging. | 24| builder | [CustomBuilder](ts-types.md#custombuilder8) | No | Custom component to display during dragging. If **pixelMap** is set, this attribute is ignored.| 25| extraInfo | string | No | Extra information of the dragged item. | 26 27 28## extraParams 29 30 Provides additional information required for dragging an item. 31 32 **extraParams** is a string converted from a JSON object. You can obtain the following attributes using the JSON object converted from **Json.parse**. 33 34| Name | Type | Description | 35| ------------- | ------ | ---------------------------------------- | 36| selectedIndex | number | Index of the dragged item in the parent container. The value of **selectedindex** starts from **0**.<br>This attribute is valid only in the drag event of the **\<ListItem>** component.| 37| insertIndex | number | Index of the element into which the dragged item is dropped in the **List** component. The value of **insertIndex** starts from **0**.<br>This attribute is valid only in the drag event of the **\<List>** component.| 38 39## DragEvent 40 41| Name | Type | Description | 42| ------ | ------ | ---------------- | 43| getX() | number | X-coordinate of the drag position relative to the upper left corner of the screen, in vp.| 44| getY() | number | Y-coordinate of the drag position relative to the upper left corner of the screen, in vp.| 45 46## Example 47 48### Example 1 49 50```ts 51@Observed 52class ClassA { 53 public name: string 54 public bol: boolean 55 56 constructor(name: string, bol: boolean) { 57 this.name = name 58 this.bol = bol 59 } 60} 61 62@Extend(Text) function textStyle() { 63 .width('25%') 64 .height(35) 65 .fontSize(16) 66 .textAlign(TextAlign.Center) 67 .backgroundColor(0xAFEEEE) 68} 69 70@Entry 71@Component 72struct DragExample { 73 @State arr: ClassA[] = [new ClassA('A', true), new ClassA('B', true), new ClassA('C', true)] 74 @State dragIndex: number = 0 75 76 changeIndex(index1: number, index2: number) {// Exchange the array position. 77 [this.arr[index1], this.arr[index2]] = [this.arr[index2], this.arr[index1]]; 78 } 79 80 build() { 81 Column() { 82 Row({ space: 15 }) { 83 List({ space: 20 }) { 84 ForEach(this.arr, (item, index) => { 85 ListItem() { 86 Column() { 87 Child({ a: this.arr[index] }) 88 } 89 .onTouch((event: TouchEvent) => { 90 if (event.type === TouchType.Down) { 91 this.dragIndex = index // Obtain the index of the current dragged child component. 92 console.info('onTouch' + this.dragIndex) 93 } 94 }) 95 } 96 }) 97 } 98 .listDirection(Axis.Horizontal) 99 .onDrop((event: DragEvent, extraParams: string) => { // The component bound to this event can be used as the drop target. When the dragging stops within the component scope, the callback is triggered. 100 let jsonString = JSON.parse(extraParams); 101 this.changeIndex(this.dragIndex, jsonString.insertIndex) 102 }) 103 }.padding({ top: 10, bottom: 10 }).margin(10) 104 105 }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 }) 106 } 107} 108 109@Component 110struct Child { 111 @ObjectLink a: ClassA 112 113 @Builder pixelMapBuilder() { 114 Column() { 115 Text(this.a.name) 116 .width('50%') 117 .height(60) 118 .fontSize(16) 119 .borderRadius(10) 120 .textAlign(TextAlign.Center) 121 .backgroundColor(Color.Yellow) 122 } 123 } 124 125 build() { 126 Column() { 127 Text(this.a.name) 128 .textStyle() 129 .visibility(this.a.bol ? Visibility.Visible : Visibility.None) 130 .onDragStart(() => { // The callback is triggered when the component bound to this event is dragged for the first time. 131 this.a.bol = false // Control the visibility. 132 return this.pixelMapBuilder() // Set the image displayed during dragging. 133 }) 134 .onTouch((event: TouchEvent) => { 135 if (event.type === TouchType.Up) { 136 this.a.bol = true 137 } 138 }) 139 Text('') 140 .width('25%') 141 .height(35) 142 .fontSize(16) 143 .textAlign(TextAlign.Center) 144 .border({ width: 5, color: 'red' }) 145 .visibility(!this.a.bol ? Visibility.Visible : Visibility.None) 146 } 147 } 148} 149``` 150 151![drag-drop](figures/drag-drop.gif) 152 153### Example 2 154 155```ts 156// xxx.ets 157@Extend(Text) function textStyle () { 158 .width('25%') 159 .height(35) 160 .fontSize(16) 161 .textAlign(TextAlign.Center) 162 .backgroundColor(0xAFEEEE) 163} 164 165@Entry 166@Component 167struct DragExample { 168 @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six'] 169 @State text: string = '' 170 @State bool: boolean = true 171 @State eventType: string = '' 172 @State appleVisible: Visibility = Visibility.Visible 173 @State orangeVisible: Visibility = Visibility.Visible 174 @State bananaVisible: Visibility = Visibility.Visible 175 private dragList: string[] = ['apple', 'orange', 'banana'] 176 @State fruitVisible: Visibility[] = [Visibility.Visible, Visibility.Visible, Visibility.Visible] 177 @State idx: number = 0 178 179 // Customize the content displayed during dragging. 180 @Builder pixelMapBuilder() { 181 Column() { 182 Text(this.text) 183 .width('50%') 184 .height(60) 185 .fontSize(16) 186 .borderRadius(10) 187 .textAlign(TextAlign.Center) 188 .backgroundColor(Color.Yellow) 189 } 190 } 191 192 build() { 193 Column() { 194 Text('There are three Text elements here') 195 .fontSize(12) 196 .fontColor(0xCCCCCC) 197 .width('90%') 198 .textAlign(TextAlign.Start) 199 .margin(5) 200 Row({ space: 15 }) { 201 ForEach(this.dragList, (item, index) => { 202 Text(item) 203 .textStyle() 204 .visibility(this.fruitVisible[index]) 205 .onDragStart(() => { 206 this.bool = true 207 this.text = item 208 this.fruitVisible[index] = Visibility.None 209 return this.pixelMapBuilder 210 }) 211 .onTouch((event: TouchEvent) => { 212 if (event.type === TouchType.Down) { 213 this.eventType = 'Down' 214 this.idx = index 215 } 216 if (event.type === TouchType.Up) { 217 this.eventType = 'Up' 218 if (this.bool) { 219 this.fruitVisible[index] = Visibility.Visible 220 } 221 } 222 }) 223 }) 224 }.padding({ top: 10, bottom: 10 }).margin(10) 225 226 Text('This is a List element') 227 .fontSize(12) 228 .fontColor(0xCCCCCC) 229 .width('90%') 230 .textAlign(TextAlign.Start) 231 .margin(15) 232 List({ space: 20 }) { 233 ForEach(this.numbers, (item) => { 234 ListItem() { 235 Text(item) 236 .width('100%') 237 .height(80) 238 .fontSize(16) 239 .borderRadius(10) 240 .textAlign(TextAlign.Center) 241 .backgroundColor(0xAFEEEE) 242 } 243 }, item => item) 244 } 245 .editMode(true) 246 .height('50%') 247 .width('90%') 248 .border({ width: 1 }) 249 .padding(15) 250 .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) 251 .onDragEnter((event: DragEvent, extraParams: string) => { 252 console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) 253 }) 254 .onDragMove((event: DragEvent, extraParams: string) => { 255 console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) 256 }) 257 .onDragLeave((event: DragEvent, extraParams: string) => { 258 console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY()) 259 }) 260 .onDrop((event: DragEvent, extraParams: string) => { 261 let jsonString = JSON.parse(extraParams); 262 if (this.bool) { 263 // Insert an element using the splice method. 264 this.numbers.splice(jsonString.insertIndex, 0, this.text) 265 this.bool = false 266 } 267 this.fruitVisible[this.idx] = Visibility.None 268 }) 269 }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 }) 270 } 271} 272``` 273 274![en-us_image_0000001252667389](figures/en-us_image_0000001252667389.gif) 275