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 provides default drag and drop capabilities 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). You can further customize drag and drop behavior by implementing universal drag events. 12 13- The following component supports drag actions by default: [Search](ts-basic-components-search.md), [TextInput](ts-basic-components-textinput.md), [TextArea](ts-basic-components-textarea.md), [RichEditor](ts-basic-components-richeditor.md), [Text](ts-basic-components-text.md), [Image](ts-basic-components-image.md), <!--Del-->[FormComponent](ts-basic-components-formcomponent-sys.md), <!--DelEnd-->[Hyperlink](ts-container-hyperlink.md). You can control the default drag behavior by setting the [draggable](ts-universal-attributes-drag-drop.md#draggable) attribute. 14 15- The following component supports drop actions by default: [Search](ts-basic-components-search.md), [TextInput](ts-basic-components-textinput.md), [TextArea](ts-basic-components-textarea.md), [RichEditor](ts-basic-components-richeditor.md). You can disable the default drag behavior by setting the [allowDrop](ts-universal-attributes-drag-drop.md#allowdrop) attribute to **null**. 16 17<!--RP1--><!--RP1End-->To 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**. 18 19> **NOTE** 20> 21> When using the **Text** component, set [copyOption](ts-basic-components-text.md#copyoption9) to **CopyOptions.InApp** or **CopyOptions.LocalDevice**. 22 23## onDragStart 24 25onDragStart(event: (event: DragEvent, extraParams?: string) => CustomBuilder | DragItemInfo) 26 27Triggered when the component bound to the event is dragged for the first time. A drag operation is recognized only when the long press time is 500 ms or longer and the dragging distance is 10 vp or larger. 28 29For components that can serve as the drag source by default, a custom **onDragStart** event, if set, is executed and: 30- If a custom drag preview is returned, it is used in place of the default drag preview. 31- If drag data is set, it is used in place of the default drag data. 32 33No custom drag preview is supported for dragging selected text in the following components: [Text](ts-basic-components-text.md), [Search](ts-basic-components-search.md), [TextInput](ts-basic-components-textinput.md), [TextArea](ts-basic-components-textarea.md), [RichEditor](ts-basic-components-richeditor.md) When **onDragStart** is used together with menu preview or any component that can serve as the drag source by default is used, custom content on menu items and the preview cannot be dragged. 34 35**Atomic service API**: This API can be used in atomic services since API version 11. 36 37**Event priority**:<br>Long press time < 500 ms: Long press event > Drag event<br>Other cases: Drag event > Long press event 38 39**System capability**: SystemCapability.ArkUI.ArkUI.Full 40 41**Parameters** 42 43| Name | Type | Mandatory| Description | 44| ----------- | ------------------------------- | ---- | ------------------ | 45| event | (event: [DragEvent](#dragevent7), extraParams?: string) => [CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](#dragiteminfo) | Yes | Callback function.<br> **NOTE**<br> **event**: information about the drag event.<br> **extraParams**: extra information about the drag event. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 46 47**Return value** 48 49| Type | Description | 50| ------------------------------------------------------------ | ------------------------ | 51| [CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](#dragiteminfo) | Component information displayed during dragging.<br>**NOTE**<br>The global builder is not supported.| 52 53## onDragEnter 54 55onDragEnter(event: (event: DragEvent, extraParams?: string) => void) 56 57Triggered when a dragged item enters a valid drop target. This event takes effect only when a listener for the [onDrop](#ondrop) event is enabled. 58 59**Atomic service API**: This API can be used in atomic services since API version 11. 60 61**System capability**: SystemCapability.ArkUI.ArkUI.Full 62 63**Parameters** 64 65| Name | Type | Mandatory| Description | 66| ----------- | ------------------------------- | ---- | ------------------------------ | 67| event | (event: [DragEvent](#dragevent7), extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<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. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 68 69## onDragMove 70 71onDragMove(event: (event: DragEvent, extraParams?: string) => void) 72 73Triggered when a dragged item moves in a valid drop target. This event takes effect only when a listener for the [onDrop](#ondrop) event is enabled. 74 75**Atomic service API**: This API can be used in atomic services since API version 11. 76 77**System capability**: SystemCapability.ArkUI.ArkUI.Full 78 79**Parameters** 80 81| Name | Type | Mandatory| Description | 82| ----------- | ------------------------------- | ---- | ------------------------------ | 83| event | (event: [DragEvent](#dragevent7), extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<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. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 84 85## onDragLeave 86 87onDragLeave(event: (event: DragEvent, extraParams?: string) => void) 88 89Triggered when a dragged item leaves a valid drop target. This event takes effect only when a listener for the [onDrop](#ondrop) event is enabled. 90 91**Atomic service API**: This API can be used in atomic services since API version 11. 92 93**System capability**: SystemCapability.ArkUI.ArkUI.Full 94 95**Parameters** 96 97| Name | Type | Mandatory| Description | 98| ----------- | ------------------------------- | ---- | ------------------------------ | 99| event | (event: [DragEvent](#dragevent7), extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<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. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 100 101## onDrop 102 103onDrop(event: (event: DragEvent, extraParams?: string) => void) 104 105Triggered when a dragged item is dropped on a valid drop target. If **event.setResult()** is not explicitly called in the **onDrop** callback to set the drag-and-drop result, then: For supported components, the result is determined based on the actual data processed; for other components, the system considers the data as successfully received. 106 107**Atomic service API**: This API can be used in atomic services since API version 11. 108 109**System capability**: SystemCapability.ArkUI.ArkUI.Full 110 111**Parameters** 112 113| Name | Type | Mandatory| Description | 114| ----------- | ------------------------------- | ---- | ------------------------------ | 115| event | (event: [DragEvent](#dragevent7), extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<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. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 116 117## onDrop<sup>16+</sup> 118 119onDrop(eventCallback: OnDragEventCallback, dropOptions?: DropOptions) 120 121Triggered when a dragged item is dropped on a valid drop target. If you do not explicitly call **event.setResult()** in **onDrop** to set the result of the drag reception, the system handles it as follows:<br>- If the component being dragged is one that supports drop actions by default, the system's actual data processing result is used.<br>- For other components, the system assumes that the data is received successfully. 122 123**Atomic service API**: This API can be used in atomic services since API version 11. 124 125**System capability**: SystemCapability.ArkUI.ArkUI.Full 126 127**Parameters** 128 129| Name | Type | Mandatory| Description | 130| ----------- | ------------------------------- | ---- | ------------------------------ | 131| eventCallback | (event: DragEvent, extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<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. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 132| dropOptions | bool | No | Whether to fetch data early during the drag operation.<br>**NOTE**<br> Set this parameter to **true** when using **startDataLoading** to prevent early data fetching.| 133 134## onDragEnd<sup>10+</sup> 135 136onDragEnd(event: (event: DragEvent, extraParams?: string) => void) 137 138Triggered when the dragging of the component bound to the event ends. 139 140**Atomic service API**: This API can be used in atomic services since API version 11. 141 142**System capability**: SystemCapability.ArkUI.ArkUI.Full 143 144**Parameters** 145 146| Name | Type | Mandatory| Description | 147| ----------- | ------------------------------- | ---- | ------------------------------ | 148| event | (event: [DragEvent](#dragevent7), extraParams?: string) => void | Yes | Callback function.<br>**NOTE**<br> **event**: information about the drag event, excluding the coordinates of the item that is being dragged.<br> **extraParams**: additional information about the drag event. The value needs to be parsed into the JSON format. For details, see [extraParams](#extraparams).| 149 150## onPreDrag<sup>12+</sup> 151 152onPreDrag(event: (preDragStatus: PreDragStatus) => void) 153 154Invoked when the component enters a state prior to a drop and drop operation. 155 156**Atomic service API**: This API can be used in atomic services since API version 12. 157 158**System capability**: SystemCapability.ArkUI.ArkUI.Full 159 160**Parameters** 161 162| Name | Type | Mandatory| Description | 163| ----------- | ------------------------------- | ---- | ------------------------------ | 164| callback | Callback<(preDragStatus: [PreDragStatus](#predragstatus12)> ) => void | Yes | Callback function.| 165 166## DragItemInfo 167 168**Atomic service API**: This API can be used in atomic services since API version 11. 169 170**System capability**: SystemCapability.ArkUI.ArkUI.Full 171 172| Name | Type | Mandatory | Description | 173| --------- | ---------------------------------------- | ---- | --------------------------------- | 174| pixelMap | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) | No | Image to be displayed during dragging.| 175| builder | [CustomBuilder](ts-types.md#custombuilder8) | No | Custom component to display during dragging. If **pixelMap** is set, this parameter is ignored.<br> **NOTE**<br>Global builder definition is not supported. If the [Image](ts-basic-components-image.md) component is used in the builder, enable synchronous loading whenever possible, that is, set the [syncLoad](ts-basic-components-image.md#syncload8) attribute of the component to **true**. The builder is used only to generate the image displayed during the current dragging. Changes to the builder, if any, apply to the next dragging, but not to the current dragging.| 176| extraInfo | string | No | Extra information of the dragged item. | 177 178## PreviewConfiguration<sup>15+</sup> 179 180Defines the preview image style during a drag operation. 181 182**Atomic service API**: This API can be used in atomic services since API version 15. 183 184**System capability**: SystemCapability.ArkUI.ArkUI.Full 185 186| Name | Type| Read-Only| Optional| Description | 187| ---------- | ---- | ---- | ---- | ------------------------------------------------------------ | 188| onlyForLifting | boolean | No | Yes | Whether the custom preview image is used only for lifting.<br> **NOTE**<br>The default value is **false**. When the value is set to **true**, the preview image is used only during the lifting phase of a long press. For the preview image used during the dragging phase: The [dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11) attribute is ignored, and the system prioritizes the image returned in [onDragStart](ts-universal-events-drag-drop.md#ondragstart); if no image is returned in **onDragStart**, the component's snapshot is used.| 189| delayCreating | boolean | No | Yes | Whether the preview builder is loaded at the time of setting.<br>The default value is **false**.| 190 191## extraParams 192 193 Provides additional information required for dragging an item. 194 195 **extraParams** is a string converted from a JSON object. You can obtain the following attributes using the JSON object converted from **Json.parse**. 196 197| Name | Type | Description | 198| ------------- | ------ | ---------------------------------------- | 199| selectedIndex | number | Index of the dragged item in the parent container. The value of **selectedindex** starts from **0**.<br>This parameter takes effect only in the drag event of the **ListItem** component.| 200| 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 takes effect only in the drag event of the **List** component.| 201 202## DragEvent<sup>7+</sup> 203 204**System capability**: SystemCapability.ArkUI.ArkUI.Full 205 206### Attributes 207 208**Atomic service API**: This API can be used in atomic services since API version 11. 209 210**System capability**: SystemCapability.ArkUI.ArkUI.Full 211 212| Name | Type | Description | 213| ------ | ------ | ---------------- | 214| useCustomDropAnimation<sup>10+</sup> | boolean | Whether to use the custom drop animation when the dragging ends.<br>If this parameter is set to **true**, the default drop animation is disabled, and the custom one is used.<br>If this parameter is set to **false** or is not set, the default drop animation is enabled. If the drop target can accept data, it will show a shrinking disappearance animation; if not, it will show an enlarging disappearance animation.<br>When the default drop animation is not disabled, avoid implementing custom animations to prevent conflicts.| 215|dragBehavior<sup>10+</sup> | [DragBehavior](#dragbehavior10) | Copy or paste mode.| 216 217### Methods 218 219**System capability**: SystemCapability.ArkUI.ArkUI.Full 220 221| Name | Return Value Type | Description | 222| ----------- | ------------------------------- | ------------------------------ | 223| setData(unifiedData: [UnifiedData](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#unifieddata))<sup>10+</sup> | void | Sets drag-related data in the drag event.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 224| getData()<sup>10+</sup> | [UnifiedData](../../apis-arkdata/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.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 225| getSummary()<sup>10+</sup> | [Summary](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#summary) | Obtains the summary of drag-related data from the drag event.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 226| setResult(dragRect: [DragResult](#dragresult10))<sup>10+</sup> | void | Sets the drag and drop result in the drag event.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 227| getResult()<sup>10+</sup> | [DragResult](#dragresult10) | Obtains the drag and drop result from the drag event.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 228| getPreviewRect()<sup>10+</sup> | [Rectangle](ts-universal-attributes-touch-target.md#rectangle) | Obtains the position of the drag preview image relative to the current window, as well as the size of the preview image, in VP units. **x** and **y** represent the coordinates of the upper left corner of the preview image, while **width** and **height** represent the size of the preview image.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 229| 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.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 230| 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.| 231| 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.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 232| getWindowX()<sup>10+</sup> | number | X coordinate of the drag position relative to the upper left corner of the window, in vp.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 233| getWindowY()<sup>10+</sup> | number | Y coordinate of the drag position relative to the upper left corner of the window, in vp.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 234| getDisplayX()<sup>10+</sup> | number | X coordinate of the drag position relative to the upper left corner of the screen, in vp.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 235| getDisplayY()<sup>10+</sup> | number | Y coordinate of the drag position relative to the upper left corner of the screen, in vp.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 236| getModifierKeyState<sup>12+</sup> | (Array<string>) => bool | Obtains the pressed status of modifier keys. For details about the error message, see the following error codes. The following modifier keys are supported: 'Ctrl'\|'Alt'\|'Shift'\|'Fn'. This API does not work for the Fn key on an externally connected keyboard.<br>**Atomic service API**: This API can be used in atomic services since API version 13.| 237| startDataLoading(options: [DataSyncOptions](#datasyncoptions15))<sup>15+</sup> | string | Asynchronously obtains drag data and notifies you of the current data synchronization progress. This API is only supported during the **onDrop** phase. Data transfer can be canceled using the [cancelDataLoading](../js-apis-arkui-UIContext.md#canceldataloading15) API.<br>**Atomic service API**: This API can be used in atomic services since API version 15.| 238| 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.| 239| 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.| 240 241 242**Error codes** 243 244For details about the error codes, see [Universal Error Codes](../../errorcode-universal.md) and [Drag Event Error Codes](../errorcode-drag-event.md). 245 246| ID | Error Message| 247| --------- | ------- | 248| 401 | Parameter error. Possible causes: 1. Incorrect parameter types. 2. Parameter verification failed. | 249| 190001 | Data not found.| 250| 190002 | Data error. | 251| 190003 | Operation on allowed for current pharse. | 252 253## DragResult<sup>10+</sup> 254 255**Atomic service API**: This API can be used in atomic services since API version 11. 256 257**System capability**: SystemCapability.ArkUI.ArkUI.Full 258 259| Name| Description| 260| ----- | ----------------- | 261| DRAG_SUCCESSFUL | The drag and drop operation succeeded. It can be used in **onDrop**.| 262| DRAG_FAILED | The drag and drop operation failed. It can be used in **onDrop**.| 263| DRAG_CANCELED | The drag and drop operation was canceled. It can be used in **onDrop**.| 264| DROP_ENABLED | The component allows for a drop operation. It can be used in **onDragMove**.| 265| DROP_DISABLED | The component does not allow for a drop operation. It can be used in **onDragMove**.| 266 267## DragBehavior<sup>10+</sup> 268 269Describes the drag behavior. When [DragResult](#dragresult10) is set to **DROP_ENABLED**, you can define **DragBehavior** as either **COPY** or **MOVE**. **DragBehavior** serves to inform you about the intended method of data handling – whether it's a copy or a move –but it does not actually dictate the real processing of the data. The behavior is reported back to the drag source through **onDragEnd**, enabling the initiator of the drag to discern whether the operation results in a copy or a move of the data. 270 271**Atomic service API**: This API can be used in atomic services since API version 11. 272 273**System capability**: SystemCapability.ArkUI.ArkUI.Full 274 275| Name| Description| 276| ----- | ----------------- | 277| COPY | The data is handled as a copy operation.| 278| MOVE| The data is handled as a move operation, effectively cutting it from its original location.| 279 280## PreDragStatus<sup>12+</sup> 281 282**Atomic service API**: This API can be used in atomic services since API version 12. 283 284**System capability**: SystemCapability.ArkUI.ArkUI.Full 285 286| Name| Value| Description| 287| ---- | - | ----------------- | 288| ACTION_DETECTING_STATUS | 0 | A drag gesture is being detected. (Triggered when the component is long pressed for 50 ms.)| 289| READY_TO_TRIGGER_DRAG_ACTION | 1 | The component is ready to be dragged. (Triggered when the component is long pressed for 500 ms.)| 290| PREVIEW_LIFT_STARTED | 2 | A lift animation is started. (Triggered when the component is long pressed for 800 ms.)| 291| PREVIEW_LIFT_FINISHED | 3 | A lift animation is finished. (Triggered at the completion of the lift animation.)| 292| PREVIEW_LANDING_STARTED | 4 | A drop animation is started. (Triggered when the drop animation starts.)| 293| PREVIEW_LANDING_FINISHED | 5 | A drop animation is finished. (Triggered when the drop animation ends.)| 294| ACTION_CANCELED_BEFORE_DRAG | 6 | A drop animation is terminated. (Triggered when the finger is lifted off the screen after the component enters the **READY_TO_TRIGGER_DRAG_ACTION** state.)| 295 296## DataSyncOptions<sup>15+</sup> 297 298type DataSyncOptions = GetDataParams 299 300Defines an input parameter for the **startDataLoading** API. 301 302**Atomic service API**: This API can be used in atomic services since API version 15. 303 304**System capability**: SystemCapability.ArkUI.ArkUI.Full 305 306| Type| Description| 307| ----- | ----------------- | 308| [GetDataParams](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#getdataparams15) | Parameters for obtaining data from UDMF, including target path, file conflict options, progress indicator type, and other relevant settings.| 309 310## Example 311 312### Example 1: Setting Draggable and Droppable Areas 313 314This example demonstrates the setup for draggable and droppable areas for certain components, such as **Image** and **Text**. 315 316```ts 317// xxx.ets 318import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData'; 319import { promptAction } from '@kit.ArkUI'; 320import { BusinessError } from '@kit.BasicServicesKit'; 321 322@Entry 323@Component 324struct Index { 325 @State targetImage: string = ''; 326 @State targetText: string = 'Drag Text'; 327 @State imageWidth: number = 100; 328 @State imageHeight: number = 100; 329 @State imgState: Visibility = Visibility.Visible; 330 @State abstractContent: string = "abstract"; 331 @State textContent: string = ""; 332 @State backGroundColor: Color = Color.Transparent; 333 334 @Builder 335 pixelMapBuilder() { 336 Column() { 337 Image($r('app.media.icon')) 338 .width(120) 339 .height(120) 340 .backgroundColor(Color.Yellow) 341 } 342 } 343 344 getDataFromUdmfRetry(event: DragEvent, callback: (data: DragEvent) => void) { 345 try { 346 let data: UnifiedData = event.getData(); 347 if (!data) { 348 return false; 349 } 350 let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords(); 351 if (!records || records.length <= 0) { 352 return false; 353 } 354 callback(event); 355 return true; 356 } catch (e) { 357 console.log("getData failed, code = " + (e as BusinessError).code + ", message = " + (e as BusinessError).message); 358 return false; 359 } 360 } 361 362 getDataFromUdmf(event: DragEvent, callback: (data: DragEvent) => void) { 363 if (this.getDataFromUdmfRetry(event, callback)) { 364 return; 365 } 366 setTimeout(() => { 367 this.getDataFromUdmfRetry(event, callback); 368 }, 1500); 369 } 370 371 private PreDragChange(preDragStatus: PreDragStatus): void { 372 if (preDragStatus == PreDragStatus.READY_TO_TRIGGER_DRAG_ACTION) { 373 this.backGroundColor = Color.Red; 374 } else if (preDragStatus == PreDragStatus.ACTION_CANCELED_BEFORE_DRAG 375 || preDragStatus == PreDragStatus.PREVIEW_LANDING_FINISHED) { 376 this.backGroundColor = Color.Blue; 377 } 378 } 379 380 build() { 381 Row() { 382 Column() { 383 Text('start Drag') 384 .fontSize(18) 385 .width('100%') 386 .height(40) 387 .margin(10) 388 .backgroundColor('#008888') 389 Image($r('app.media.icon')) 390 .width(100) 391 .height(100) 392 .draggable(true) 393 .margin({ left: 15 }) 394 .visibility(this.imgState) 395 .onDragEnd((event) => { 396 // The result value obtained from onDragEnd is set in onDrop of the drop target. 397 if (event.getResult() === DragResult.DRAG_SUCCESSFUL) { 398 promptAction.showToast({ duration: 100, message: 'Drag Success' }); 399 } else if (event.getResult() === DragResult.DRAG_FAILED) { 400 promptAction.showToast({ duration: 100, message: 'Drag failed' }); 401 } 402 }) 403 Text('test drag event') 404 .width('100%') 405 .height(100) 406 .draggable(true) 407 .margin({ left: 15 }) 408 .copyOption(CopyOptions.InApp) 409 TextArea({ placeholder: 'please input words' }) 410 .copyOption(CopyOptions.InApp) 411 .width('100%') 412 .height(50) 413 .draggable(true) 414 Search({ placeholder: 'please input you word' }) 415 .searchButton('Search') 416 .width('100%') 417 .height(80) 418 .textFont({ size: 20 }) 419 420 Column() { 421 Text('this is abstract') 422 .fontSize(20) 423 .width('100%') 424 }.margin({ left: 40, top: 20 }) 425 .width('100%') 426 .height(100) 427 .onDragStart((event) => { 428 this.backGroundColor = Color.Transparent; 429 let data: unifiedDataChannel.PlainText = new unifiedDataChannel.PlainText(); 430 data.abstract = 'this is abstract'; 431 data.textContent = 'this is content this is content'; 432 (event as DragEvent).setData(new unifiedDataChannel.UnifiedData(data)); 433 }) 434 .onPreDrag((status: PreDragStatus) => { 435 this.PreDragChange(status); 436 }) 437 .backgroundColor(this.backGroundColor) 438 }.width('45%') 439 .height('100%') 440 441 Column() { 442 Text('Drag Target Area') 443 .fontSize(20) 444 .width('100%') 445 .height(40) 446 .margin(10) 447 .backgroundColor('#008888') 448 Image(this.targetImage) 449 .width(this.imageWidth) 450 .height(this.imageHeight) 451 .draggable(true) 452 .margin({ left: 15 }) 453 .border({ color: Color.Black, width: 1 }) 454 .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE]) 455 .onDrop((dragEvent?: DragEvent) => { 456 this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => { 457 let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords(); 458 let rect: Rectangle = event.getPreviewRect(); 459 this.imageWidth = Number(rect.width); 460 this.imageHeight = Number(rect.height); 461 this.targetImage = (records[0] as unifiedDataChannel.Image).imageUri; 462 event.useCustomDropAnimation = false; 463 this.imgState = Visibility.None; 464 // If result is explicitly set to successful, the value is passed in to onDragEnd of the drag source. 465 event.setResult(DragResult.DRAG_SUCCESSFUL); 466 }) 467 }) 468 469 Text(this.targetText) 470 .width('100%') 471 .height(100) 472 .border({ color: Color.Black, width: 1 }) 473 .margin(15) 474 .allowDrop([uniformTypeDescriptor.UniformDataType.PLAIN_TEXT]) 475 .onDrop((dragEvent?: DragEvent) => { 476 this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => { 477 let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords(); 478 let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText; 479 this.targetText = plainText.textContent; 480 }) 481 }) 482 483 Column() { 484 Text(this.abstractContent).fontSize(20).width('100%') 485 Text(this.textContent).fontSize(15).width('100%') 486 } 487 .width('100%') 488 .height(100) 489 .margin(20) 490 .border({ color: Color.Black, width: 1 }) 491 .allowDrop([uniformTypeDescriptor.UniformDataType.PLAIN_TEXT]) 492 .onDrop((dragEvent?: DragEvent) => { 493 this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => { 494 let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords(); 495 let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText; 496 this.abstractContent = plainText.abstract as string; 497 this.textContent = plainText.textContent; 498 }) 499 }) 500 }.width('45%') 501 .height('100%') 502 .margin({ left: '5%' }) 503 } 504 .height('100%') 505 } 506} 507``` 508 509 510### Example 2: Obtaining Data Asynchronously Through Drag-and-Drop 511 512This example demonstrates how to asynchronously obtain data using **startDataLoading** during a drag-and-drop operation. 513 514```ts 515import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData'; 516import { fileUri, fileIo as fs } from '@kit.CoreFileKit' 517import { common } from '@kit.AbilityKit' 518 519@Entry 520@Component 521struct ImageExample { 522 @State uri: string = ""; 523 @State blockArr: string[] = []; 524 udKey: string = ''; 525 526 build() { 527 Column() { 528 Text('Image drag and drop') 529 .fontSize('30dp') 530 Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) { 531 Image($r('app.media.startIcon')) 532 .width(100) 533 .height(100) 534 .border({ width: 1 }) 535 .draggable(true) 536 .onDragStart((event:DragEvent) => { 537 const context: Context = getContext(this); 538 let data = context.resourceManager.getMediaContentSync($r('app.media.startIcon').id, 120); 539 const arrayBuffer: ArrayBuffer = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset); 540 let filePath = context.filesDir + '/test.png'; 541 let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); 542 fs.writeSync(file.fd, arrayBuffer); 543 // Obtain the image URI. 544 let uri = fileUri.getUriFromPath(filePath); 545 let image: unifiedDataChannel.Image = new unifiedDataChannel.Image(); 546 image.imageUri = uri; 547 let dragData: unifiedDataChannel.UnifiedData = new unifiedDataChannel.UnifiedData(image); 548 (event as DragEvent).setData(dragData); 549 }) 550 } 551 .margin({ bottom: 20 }) 552 Row() { 553 Column(){ 554 Text('Valid drop target') 555 .fontSize('15dp') 556 .height('10%') 557 List(){ 558 ForEach(this.blockArr, (item:string, index) => { 559 ListItem() { 560 Image(item) 561 .width(100) 562 .height(100) 563 .border({width: 1}) 564 } 565 .margin({ left: 30 , top : 30}) 566 }, (item:string) => item) 567 } 568 .border({width: 1}) 569 .height('90%') 570 .width('100%') 571 .onDrop((event?: DragEvent, extraParams?: string) => { 572 console.log("enter onDrop") 573 let context = getContext(this) as common.UIAbilityContext; 574 let pathDir: string = context.distributedFilesDir; 575 let destUri = fileUri.getUriFromPath(pathDir); 576 let progressListener: unifiedDataChannel.DataProgressListener = (progress: unifiedDataChannel.ProgressInfo, dragData: UnifiedData|null) => { 577 if(dragData != null) { 578 let arr:Array<unifiedDataChannel.UnifiedRecord> = dragData.getRecords(); 579 if(arr.length > 0) { 580 if (arr[0].getType() === uniformTypeDescriptor.UniformDataType.IMAGE) { 581 let image = arr[0] as unifiedDataChannel.Image; 582 this.uri = image.imageUri; 583 this.blockArr.splice(JSON.parse(extraParams as string).insertIndex, 0, this.uri); 584 } 585 } else { 586 console.log('dragData arr is null'); 587 } 588 } else { 589 console.log('dragData is undefined'); 590 } 591 console.log(`percentage: ${progress.progress}`); 592 }; 593 let options: DataSyncOptions = { 594 destUri: destUri, 595 fileConflictOptions: unifiedDataChannel.FileConflictOptions.OVERWRITE, 596 progressIndicator: unifiedDataChannel.ProgressIndicator.DEFAULT, 597 dataProgressListener: progressListener, 598 } 599 try { 600 this.udKey = (event as DragEvent).startDataLoading(options); 601 console.log('udKey: ', this.udKey); 602 } catch(e) { 603 console.log(`startDataLoading errorCode: ${e.code}, errorMessage: ${e.message}`); 604 } 605 }, {disableDataPrefetch: true}) 606 } 607 .height("50%") 608 .width("90%") 609 .border({ width: 1 }) 610 } 611 Button('Cancel data transfer') 612 .onClick(() => { 613 try { 614 this.getUIContext().getDragController().cancelDataLoading(this.udKey); 615 } catch (e) { 616 console.log(`cancelDataLoading errorCode: ${e.code}, errorMessage: ${e.message}`); 617 } 618 }) 619 .margin({top: 10}) 620 }.width('100%') 621 } 622} 623``` 624<!--no_check-->