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> The resource files preset in the application (that is, the resource files that are contained in the HAP file before the application is installed) can be dragged and dropped only within the application. 10 11The ArkUI framework implements the drag and drop capability for the following components, allowing them to serve as the drag source (from which data can be dragged) or drop target (to which data can be dropped). To enable drag and drop for these components, you only need to set their [draggable](ts-universal-attributes-drag-drop.md) attribute to **true**. 12 13- The following component supports drag actions by default: **\<Search>**, **\<TextInput>**, **\<TextArea>**, **\<RichEditor>**, **\<Text>**, **\<Image>**, **\<FormComponent>**, **\<Hyperlink>** 14 15- The following component supports drop actions by default: **\<Search>**, **\<TextInput>**, **\<TextArea>**, **\<Video>** 16 17You can also define drag responses by implementing common drag events. 18 19To enable drag and drop for other components, you need to set the **draggable** attribute to **true** and implement data transmission in APIs such as **onDragStart**. 20 21 22## Events 23 24| Name | Bubbling Supported| Description | 25| ------------------------------------------------------------ | -------- | ------------------------------------------------------------ | 26| 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. For details, see [DragEvent](#dragevent).<br>- **extraParams**: additional information about the drag event. For details, see **[extraParams](#extraparams)**.<br> Return value: component information displayed during dragging.<br>Trigger condition: long press for at least 500 ms.<br> Event priority:<br>- Long press time < 500 ms: Long press event > Drag event<br> - Other: Drag event > Long press event| 27| 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.| 28| 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.| 29| 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.| 30| 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)**.| 31| onDragEnd(event: (event?: [DragEvent](#dragevent), extraParams?: string) => void)<sup>10+</sup> | No | Triggered when the dragging of the component bound to the event ends.<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)**.| 32 33## DragItemInfo 34 35| Name | Type | Mandatory | Description | 36| --------- | ---------------------------------------- | ---- | --------------------------------- | 37| pixelMap | [PixelMap](../apis/js-apis-image.md#pixelmap7) | No | Image to be displayed during dragging. | 38| builder | [CustomBuilder](ts-types.md#custombuilder8) | No | Custom component to display during dragging. If **pixelMap** is set, this attribute is ignored.| 39| extraInfo | string | No | Extra information of the dragged item. | 40 41 42## extraParams 43 44 Provides additional information required for dragging an item. 45 46 **extraParams** is a string converted from a JSON object. You can obtain the following attributes using the JSON object converted from **Json.parse**. 47 48| Name | Type | Description | 49| ------------- | ------ | ---------------------------------------- | 50| selectedIndex | number | Index of the dragged item in the parent container. The value of **selectedindex** starts from **0**.<br>This parameter is valid only in the drag event of the **\<ListItem>** component.| 51| 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 parameter is valid only in the drag event of the **\<List>** component.| 52 53## DragEvent 54 55| Name | Type | Description | 56| ------ | ------ | ---------------- | 57| useCustomDropAnimation<sup>10+</sup> | boolean | Whether to use the default drop animation when the dragging ends.| 58| setData(unifiedData: [UnifiedData](../apis/js-apis-data-unifiedDataChannel.md#unifieddata))<sup>10+</sup> | void | Sets drag-related data in the drag event.| 59| getData()<sup>10+</sup> | [UnifiedData](../apis/js-apis-data-unifiedDataChannel.md#unifieddata) | Obtains drag-related data from the drag event. For details about the data obtaining result, see the error code description.| 60| getSummary()<sup>10+</sup> | [Summary](../apis/js-apis-data-unifiedDataChannel.md#summary) | Obtains the summary of drag-related data from the drag event.| 61| setResult(dragRect: [DragResult](#dragresult10))<sup>10+</sup> | void | Sets the drag and drop result in the drag event.| 62| getResult()<sup>10+</sup> | [DragResult](#dragresult10) | Obtains the drag and drop result from the drag event.| 63| getPreviewRect()<sup>10+</sup> | [Rectangle](ts-universal-attributes-touch-target.md#rectangle) | Obtains the rectangle where the preview image is located.| 64| getVelocityX()<sup>10+</sup> | number | Obtains the dragging velocity along the x-axis. The origin of the coordinate axis is the upper left corner of the screen. The unit is vp. The velocity is positive if the movement is from left to right, and it is negative if the movement is from right to left.| 65| getVelocityY()<sup>10+</sup> | number | Obtains the dragging velocity along the y-axis. The origin of the coordinate axis is the upper left corner of the screen. The unit is vp. The velocity is positive if the movement is from top to bottom, and it is negative if the movement is from bottom to top.| 66| getVelocity()<sup>10+</sup> | number | Obtains the dragging velocity along the main axis. The value is the arithmetic square root of the sum of squares of the velocity along the x- and y-axis.| 67| getWindowX()<sup>10+</sup> | number | X coordinate of the drag position relative to the upper left corner of the window, in vp.| 68| getWindowY()<sup>10+</sup> | number | Y coordinate of the drag position relative to the upper left corner of the window, in vp.| 69| getDisplayX()<sup>10+</sup> | number | X coordinate of the drag position relative to the upper left corner of the screen, in vp.| 70| getDisplayY()<sup>10+</sup> | number | Y coordinate of the drag position relative to the upper left corner of the screen, in vp.| 71| getX()<sup>(deprecated)</sup> | number | X coordinate of the drag position relative to the upper left corner of the window, in vp.<br>This API is deprecated since API version 10. You are advised to use **getWindowX()** instead.| 72| getY()<sup>(deprecated)</sup> | number | Y coordinate of the drag position relative to the upper left corner of the window, in vp.<br>This API is deprecated since API version 10. You are advised to use **getWindowY()** instead.| 73 74**Error codes** 75 76For details about the error codes, see [Drag Event Error Codes](../errorcodes/errorcode-drag-event.md). 77 78| ID | Error Message| 79| --------- | ------- | 80| 190001 | GetData failed, data not found. | 81| 190002 | GetData failed, data error. | 82 83## DragResult<sup>10+</sup> 84 85| Name| Description| 86| ----- | ----------------- | 87| DRAG_SUCCESSFUL | The drag and drop operation succeeded.| 88| DRAG_FAILED | The drag and drop operation failed.| 89| DRAG_CANCELED | The drag and drop operation was canceled.| 90| DROP_ENABLED | The component allows for a drop operation.| 91| DROP_DISABLED | The component does not allow for a drop operation.| 92 93## Example 94 95```ts 96import UDC from '@ohos.data.unifiedDataChannel'; 97import UTD from '@ohos.data.uniformTypeDescriptor'; 98import promptAction from '@ohos.promptAction'; 99import { BusinessError } from '@ohos.base'; 100 101@Entry 102@Component 103struct Index { 104 @State targetImage: string = ''; 105 @State targetText: string = 'Drag Text'; 106 @State imageWidth: number = 100; 107 @State imageHeight: number = 100; 108 @State imgState: Visibility = Visibility.Visible; 109 @State videoSrc: string = 'resource://RAWFILE/02.mp4'; 110 @State abstractContent: string = "abstract"; 111 @State textContent: string = ""; 112 113 getDataFromUdmfRetry(event: DragEvent, callback: (data: DragEvent)=>void) 114 { 115 try { 116 let data:UnifiedData = event.getData(); 117 if (!data) { 118 return false; 119 } 120 let records: Array<UDC.UnifiedRecord> = data.getRecords(); 121 if (!records || records.length <= 0) { 122 return false; 123 } 124 callback(event); 125 return true; 126 } catch (e) { 127 console.log("getData failed, code = " + (e as BusinessError).code + ", message = " + (e as BusinessError).message); 128 return false; 129 } 130 } 131 132 getDataFromUdmf(event: DragEvent, callback: (data: DragEvent)=>void) 133 { 134 if(this.getDataFromUdmfRetry(event, callback)) { 135 return; 136 } 137 setTimeout(()=>{ 138 this.getDataFromUdmfRetry(event, callback); 139 }, 1500); 140 } 141 142 build() { 143 Row() { 144 Column() { 145 Text('start Drag') 146 .fontSize(18) 147 .width('100%') 148 .height(40) 149 .margin(10) 150 .backgroundColor('#008888') 151 Image($r('app.media.icon')) 152 .width(100) 153 .height(100) 154 .draggable(true) 155 .margin({left: 15}) 156 .visibility(this.imgState) 157 .onDragEnd((event)=>{ 158 if (event.getResult() === DragResult.DRAG_SUCCESSFUL) { 159 promptAction.showToast({duration: 100, message: 'Drag Success'}); 160 } else if (event.getResult() === DragResult.DRAG_FAILED) { 161 promptAction.showToast({duration: 100, message: 'Drag failed'}); 162 } 163 }) 164 Text('test drag event') 165 .width('100%') 166 .height(100) 167 .draggable(true) 168 .margin({left: 15}) 169 .copyOption(CopyOptions.InApp) 170 TextArea({placeholder: 'please input words'}) 171 .copyOption(CopyOptions.InApp) 172 .width('100%') 173 .height(50) 174 .draggable(true) 175 Search({placeholder: 'please input you word'}) 176 .searchButton('Search') 177 .width('100%') 178 .height(80) 179 .textFont({size: 20}) 180 Column() { 181 Text('change video source') 182 }.draggable(true) 183 .onDragStart((event)=>{ 184 let video: UDC.Video = new UDC.Video(); 185 video.videoUri = '/resources/rawfile/01.mp4'; 186 let data: UDC.UnifiedData = new UDC.UnifiedData(video); 187 (event as DragEvent).setData(data); 188 }) 189 Column() { 190 Text('this is abstract') 191 .fontSize(20) 192 .width('100%') 193 }.margin({left: 40, top: 20}) 194 .width('100%') 195 .height(100) 196 .onDragStart((event)=>{ 197 let data: UDC.PlainText = new UDC.PlainText(); 198 data.abstract = 'this is abstract'; 199 data.textContent = 'this is content this is content'; 200 (event as DragEvent).setData(new UDC.UnifiedData(data)); 201 }) 202 }.width('45%') 203 .height('100%') 204 Column() { 205 Text('Drag Target Area') 206 .fontSize(20) 207 .width('100%') 208 .height(40) 209 .margin(10) 210 .backgroundColor('#008888') 211 Image(this.targetImage) 212 .width(this.imageWidth) 213 .height(this.imageHeight) 214 .draggable(true) 215 .margin({left: 15}) 216 .border({color: Color.Black, width: 1}) 217 .allowDrop([UTD.UniformDataType.IMAGE]) 218 .onDrop((dragEvent?: DragEvent)=> { 219 this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => { 220 let records: Array<UDC.UnifiedRecord> = event.getData().getRecords(); 221 let rect: Rectangle = event.getPreviewRect(); 222 this.imageWidth = Number(rect.width); 223 this.imageHeight = Number(rect.height); 224 this.targetImage = (records[0] as UDC.Image).imageUri; 225 event.useCustomDropAnimation = false; 226 animateTo({duration: 1000}, ()=>{ 227 this.imageWidth = 100; 228 this.imageHeight = 100; 229 this.imgState = Visibility.None; 230 }) 231 event.setResult(DragResult.DRAG_SUCCESSFUL); 232 }) 233 }) 234 235 Text(this.targetText) 236 .width('100%') 237 .height(100) 238 .border({color: Color.Black, width: 1}) 239 .margin(15) 240 .allowDrop([UTD.UniformDataType.TEXT]) 241 .onDrop((dragEvent?: DragEvent)=>{ 242 this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => { 243 let records:Array<UDC.UnifiedRecord> = event.getData().getRecords(); 244 let plainText:UDC.PlainText = records[0] as UDC.PlainText; 245 this.targetText = plainText.textContent; 246 }) 247 }) 248 249 Video({src: this.videoSrc, previewUri: $r('app.media.icon')}) 250 .width('100%') 251 .height(200) 252 .controls(true) 253 .allowDrop([UTD.UniformDataType.VIDEO]) 254 255 Column() { 256 Text(this.abstractContent).fontSize(20).width('100%') 257 Text(this.textContent).fontSize(15).width('100%') 258 }.width('100%').height(100).margin(20).border({color: Color.Black, width: 1}) 259 .allowDrop([UTD.UniformDataType.PLAIN_TEXT]) 260 .onDrop((dragEvent?: DragEvent)=>{ 261 this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => { 262 let records: Array<UDC.UnifiedRecord> = event.getData().getRecords(); 263 let plainText: UDC.PlainText = records[0] as UDC.PlainText; 264 this.abstractContent = plainText.abstract as string; 265 this.textContent = plainText.textContent; 266 }) 267 }) 268 }.width('45%') 269 .height('100%') 270 .margin({left: '5%'}) 271 } 272 .height('100%') 273 } 274} 275``` 276