1# @ohos.arkui.dragController (DragController) 2 3The **dragController** module provides APIs for initiating drag actions. When receiving a gesture event, such as a touch or long-press event, an application can initiate a drag action and carry drag information therein. 4 5> **NOTE** 6> 7> The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version. 8> The functionality of this module depends on UI context. This means that the APIs of this module cannot be used where the UI context is unclear. For details, see [UIContext](js-apis-arkui-UIContext.md#uicontext). 9> Since API version 10, you can use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in **UIContext** to obtain the **DragController** object associated with the current UI context. 10> You can preview how this component looks on a real device, but not in DevEco Studio Previewer. 11 12## Modules to Import 13 14```ts 15import { dragController } from "@kit.ArkUI"; 16``` 17 18## dragController.executeDrag 19 20executeDrag(custom: CustomBuilder | DragItemInfo, dragInfo: DragInfo,callback:AsyncCallback\<DragEventParam>): void 21 22Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses an asynchronous callback to return the result. 23 24**Atomic service API**: This API can be used in atomic services since API version 12. 25 26**System capability**: SystemCapability.ArkUI.ArkUI.Full 27 28**Parameters** 29 30| Name | Type | Mandatory| Description | 31| -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | 32| custom | [CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo) | Yes | Object to be dragged.<br>**NOTE**<br>The global builder is not supported. If the [Image](arkui-ts/ts-basic-components-image.md) component is used in the builder, enable synchronous loading, that is, set the [syncLoad](arkui-ts/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.| 33| dragInfo | [DragInfo](#draginfo) | Yes | Drag information. | 34| callback | [AsyncCallback](../apis-basic-services-kit/js-apis-base.md#asynccallback)<[DragEventParam](#drageventparam12)> | Yes | Callback used to return the result. | 35 36**Error codes** 37 38For details about the error codes, see [Universal Error Codes](../errorcode-universal.md). 39 40| ID| Error Message | 41| -------- | ------------- | 42| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 43| 100001 | Internal handling failed. | 44 45**Example** 46 47> **NOTE** 48> 49> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 50 51```ts 52import { dragController } from "@kit.ArkUI"; 53import { unifiedDataChannel } from '@kit.ArkData'; 54 55@Entry 56@Component 57struct DragControllerPage { 58 @State text: string = '' 59 60 @Builder DraggingBuilder() { 61 Column() { 62 Text("DraggingBuilder") 63 .fontColor(Color.White) 64 .fontSize(12) 65 } 66 .width(100) 67 .height(100) 68 .backgroundColor(Color.Blue) 69 } 70 71 build() { 72 Column() { 73 Button('touch to execute drag') 74 .margin(10) 75 .onTouch((event?:TouchEvent) => { 76 if(event){ 77 if (event.type == TouchType.Down) { 78 let text = new unifiedDataChannel.PlainText() 79 text.textContent = 'drag text' 80 text.abstract = 'abstract' 81 let unifiedData = new unifiedDataChannel.UnifiedData(text) 82 83 let dragInfo: dragController.DragInfo = { 84 pointerId: 0, 85 data: unifiedData, 86 extraParams: '' 87 } 88 class tmp{ 89 event:DragEvent|undefined = undefined 90 extraParams:string = '' 91 } 92 let eve:tmp = new tmp() 93 dragController.executeDrag(()=>{this.DraggingBuilder()}, dragInfo, (err, eve) => { // You are advised to use this.getUIContext().getDragController().executeDrag(). 94 if(eve.event){ 95 if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) { 96 // ... 97 } else if (eve.event.getResult() == DragResult.DRAG_FAILED) { 98 // ... 99 } 100 } 101 }) 102 } 103 } 104 }) 105 Text(this.text) 106 .height(100) 107 .width(150) 108 .margin({top:20}) 109 .border({color:Color.Black,width:1}) 110 .onDrop((dragEvent?:DragEvent)=>{ 111 if(dragEvent){ 112 let records: Array<unifiedDataChannel.UnifiedRecord> = dragEvent.getData().getRecords(); 113 let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText; 114 this.text = plainText.textContent; 115 } 116 }) 117 } 118 .width('100%') 119 .height('100%') 120 } 121} 122``` 123  124## dragController.executeDrag 125 126executeDrag(custom: CustomBuilder | DragItemInfo, dragInfo: DragInfo): Promise\<DragEventParam> 127 128Initiates a drag action, with the object to be dragged and the drag information passed in. This API uses a promise to return the result. 129 130**Atomic service API**: This API can be used in atomic services since API version 12. 131 132**System capability**: SystemCapability.ArkUI.ArkUI.Full 133 134**Parameters** 135 136| Name | Type | Mandatory| Description | 137| -------- | ------------------------------------------------------------ | ---- | -------------------------------- | 138| custom | [CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo) | Yes | Object to be dragged.| 139| dragInfo | [DragInfo](#draginfo) | Yes | Drag information. | 140 141**Return value** 142 143| Type | Description | 144| -------------------------------------------------- | ------------------------ | 145| Promise<[DragEventParam](#drageventparam12)> | Promise used to return the result.| 146 147**Error codes** 148For details about the error codes, see [Universal Error Codes](../errorcode-universal.md). 149| ID| Error Message | 150| -------- | ------------- | 151| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 152| 100001 | Internal handling failed. | 153 154**Example** 155 156> **NOTE** 157> 158> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 159 160```ts 161import { dragController, componentSnapshot } from "@kit.ArkUI" 162import { image } from '@kit.ImageKit'; 163import { unifiedDataChannel } from '@kit.ArkData'; 164 165@Entry 166@Component 167struct DragControllerPage { 168 @State pixmap: image.PixelMap|undefined = undefined 169 @State text: string = '' 170 171 @Builder DraggingBuilder() { 172 Column() { 173 Text("DraggingBuilder") 174 .fontColor(Color.White) 175 } 176 .width(100) 177 .height(100) 178 .backgroundColor(Color.Blue) 179 } 180 181 @Builder PixmapBuilder() { 182 Column() { 183 Text("PixmapBuilder") 184 .fontColor(Color.White) 185 .fontSize(15) 186 } 187 .width(100) 188 .height(100) 189 .backgroundColor(Color.Blue) 190 } 191 192 aboutToAppear() { 193 let pb: CustomBuilder = (): void => { 194 this.PixmapBuilder() 195 } 196 componentSnapshot.createFromBuilder(pb).then((pix: image.PixelMap) => { 197 this.pixmap = pix; 198 }) 199 } 200 201 build() { 202 Column() { 203 Button('touch to execute drag') 204 .margin(10) 205 .onTouch((event?:TouchEvent) => { 206 if(event){ 207 if (event.type == TouchType.Down) { 208 let text = new unifiedDataChannel.PlainText() 209 text.textContent = 'drag text' 210 text.abstract = 'abstract' 211 let unifiedData = new unifiedDataChannel.UnifiedData(text) 212 213 let dragInfo: dragController.DragInfo = { 214 pointerId: 0, 215 data: unifiedData, 216 extraParams: '' 217 } 218 let dragItemInfo: DragItemInfo = { 219 pixelMap: this.pixmap, 220 builder: ()=>{this.DraggingBuilder()}, 221 extraInfo: "DragItemInfoTest" 222 } 223 224 class tmp{ 225 event:DragResult|undefined = undefined 226 extraParams:string = '' 227 } 228 let eve:tmp = new tmp() 229 dragController.executeDrag(dragItemInfo, dragInfo) // You are advised to use this.getUIContext().getDragController().executeDrag(). 230 .then((eve) => { 231 if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) { 232 // ... 233 } else if (eve.event.getResult() == DragResult.DRAG_FAILED) { 234 // ... 235 } 236 }) 237 .catch((err:Error) => { 238 }) 239 } 240 } 241 }) 242 Text(this.text) 243 .height(100) 244 .width(150) 245 .margin({top:20}) 246 .border({color:Color.Black,width:1}) 247 .onDrop((dragEvent?:DragEvent)=>{ 248 if(dragEvent){ 249 let records: Array<unifiedDataChannel.UnifiedRecord> = dragEvent.getData().getRecords(); 250 let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText; 251 this.text = plainText.textContent; 252 } 253 }) 254 } 255 .width('100%') 256 .height('100%') 257 } 258} 259``` 260  261## DragInfo 262 263**Atomic service API**: This API can be used in atomic services since API version 12. 264 265**System capability**: SystemCapability.ArkUI.ArkUI.Full 266 267Defines the attributes required for initiating a drag action and information carried in the dragging process. 268 269| Name | Type | Mandatory| Description | 270| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- | 271| pointerId | number | Yes | ID of the touch point on the screen when dragging is started. | 272| data | [unifiedDataChannel.UnifiedData](../apis-arkdata/js-apis-data-unifiedDataChannel.md#unifieddata) | No | Data carried in the dragging process. | 273| extraParams | string | No | Additional information about the drag action. Not supported currently.| 274| touchPoint<sup>11+</sup> | [TouchPoint](arkui-ts/ts-types.md#touchpoint11) | No | Coordinates of the touch point. If this parameter is not set, the touch point is centered.| 275| previewOptions<sup>11+</sup>| [DragPreviewOptions](arkui-ts/ts-universal-attributes-drag-drop.md#dragpreviewoptions11) | No | Custom configuration of the drag preview.| 276 277## dragController.createDragAction<sup>11+</sup> 278 279createDragAction(customArray: Array<CustomBuilder \| DragItemInfo>, dragInfo: DragInfo): DragAction 280 281Creates a drag action object for initiating drag and drop operations. You need to explicitly specify one or more drag previews, the drag data, and the drag handle point. If a drag operation initiated by an existing drag action object is not completed, no new object can be created, and calling the API will throw an exception. After the lifecycle of the drag action object ends, the callback functions registered on this object become invalid. Therefore, it is necessary to hold this object within a longer scope and replace the old value with a new object returned by **createDragAction** before each drag initiation. 282 283**NOTE**<br>You are advised to control the number of drag previews. If too many previews are passed in, the drag efficiency may be affected. 284 285**Atomic service API**: This API can be used in atomic services since API version 12. 286 287**System capability**: SystemCapability.ArkUI.ArkUI.Full 288 289**Parameters** 290 291| Name | Type | Mandatory| Description | 292| -------- | ------------------------------------------------------------ | ---- | -------------------------------- | 293| customArray | Array<[CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo)> | Yes | Object to be dragged.| 294| dragInfo | [DragInfo](#draginfo) | Yes | Drag information. | 295 296**Return value** 297 298| Type | Description | 299| ------------------------------------------------------ | ------------------ | 300| [DragAction](#dragaction11)| **DragAction** object, which is used to subscribe to drag state changes and start the drag service.| 301 302**Error codes** 303 304For details about the error codes, see [Universal Error Codes](../errorcode-universal.md). 305| ID| Error Message | 306| -------- | ------------- | 307| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 308| 100001 | Internal handling failed. | 309 310**Example** 311 312> **NOTE** 313> 314> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 315 316```ts 317import { dragController, componentSnapshot } from "@kit.ArkUI"; 318import { image } from '@kit.ImageKit'; 319import { unifiedDataChannel } from '@kit.ArkData'; 320 321@Entry 322@Component 323struct DragControllerPage { 324 @State pixmap: image.PixelMap | null = null 325 @State text: string = '' 326 private dragAction: dragController.DragAction | null = null; 327 customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 328 @Builder DraggingBuilder() { 329 Column() { 330 Text("DraggingBuilder") 331 .fontColor(Color.White) 332 .fontSize(12) 333 } 334 .width(100) 335 .height(100) 336 .backgroundColor(Color.Blue) 337 } 338 339 build() { 340 Column() { 341 342 Column() { 343 Text(this.text) 344 .width('100%') 345 .height('100%') 346 .fontColor(Color.White) 347 .fontSize(18) 348 .onDrop((dragEvent?:DragEvent)=>{ 349 if(dragEvent){ 350 let records: Array<unifiedDataChannel.UnifiedRecord> = dragEvent.getData().getRecords(); 351 let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText; 352 this.text = plainText.textContent; 353 } 354 }) 355 } 356 .width(100) 357 .height(100) 358 .backgroundColor(Color.Red) 359 .margin(10) 360 361 Button('Drag Multiple Objects').onTouch((event?:TouchEvent) => { 362 if(event){ 363 if (event.type == TouchType.Down) { 364 console.info("muti drag Down by listener"); 365 this.customBuilders.splice(0, this.customBuilders.length); 366 this.customBuilders.push(()=>{this.DraggingBuilder()}); 367 this.customBuilders.push(()=>{this.DraggingBuilder()}); 368 this.customBuilders.push(()=>{this.DraggingBuilder()}); 369 let text = new unifiedDataChannel.PlainText() 370 text.textContent = 'drag text' 371 let unifiedData = new unifiedDataChannel.UnifiedData(text) 372 let dragInfo: dragController.DragInfo = { 373 pointerId: 0, 374 data: unifiedData, 375 extraParams: '' 376 } 377 try{ 378 this.dragAction = dragController.createDragAction(this.customBuilders, dragInfo) // You are advised to use this.getUIContext().getDragController().createDragAction(). 379 if(!this.dragAction){ 380 console.info("listener dragAction is null"); 381 return 382 } 383 this.dragAction.on('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{ 384 if (dragAndDropInfo.status == dragController.DragStatus.STARTED) { 385 console.info("drag has start"); 386 } else if (dragAndDropInfo.status == dragController.DragStatus.ENDED){ 387 console.info("drag has end"); 388 if (!this.dragAction) { 389 return 390 } 391 this.dragAction.off('statusChange') 392 } 393 }) 394 this.dragAction.startDrag().then(()=>{}).catch((err:Error)=>{ 395 console.info("start drag Error:" + err.message); 396 }) 397 } catch(err) { 398 console.info("create dragAction Error:" + err.message); 399 } 400 } 401 } 402 }).margin({top:20}) 403 } 404 } 405} 406``` 407  408## DragAction<sup>11+</sup> 409 410Implements a **DragAction** object to subscribe to drag state changes and start the drag service. 411 412**Atomic service API**: This API can be used in atomic services since API version 12. 413 414**System capability**: SystemCapability.ArkUI.ArkUI.Full 415 416### startDrag<sup>11+</sup> 417 418startDrag(): Promise<void> 419 420Starts the drag service. This API uses a promise to return the result. 421 422**Atomic service API**: This API can be used in atomic services since API version 12. 423 424**System capability**: SystemCapability.ArkUI.ArkUI.Full 425 426**Error codes** 427 428| ID| Error Message | 429| -------- | ------------- | 430| 100001 | Internal handling failed. | 431 432**Example** 433 434> **NOTE** 435> 436> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 437 438```ts 439import { dragController } from "@kit.ArkUI" 440import { unifiedDataChannel } from '@kit.ArkData'; 441 442@Entry 443@Component 444struct DragControllerPage { 445 build() { 446 Column() { 447 Button('touch to execute drag') 448 .onTouch((event?:TouchEvent) => { 449 let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 450 let text = new unifiedDataChannel.Text() 451 let unifiedData = new unifiedDataChannel.UnifiedData(text) 452 let dragInfo: dragController.DragInfo = { 453 pointerId: 0, 454 data: unifiedData, 455 extraParams: '' 456 } 457 try { 458 let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo); // You are advised to use this.getUIContext().getDragController().createDragAction(). 459 if(!dragAction){ 460 console.info("listener dragAction is null"); 461 return 462 } 463 dragAction.startDrag().then(()=>{}).catch((err:Error)=>{ 464 console.info("start drag Error:" + err.message); 465 }) 466 } catch (err) { 467 console.info("create dragAction Error:" + err.message); 468 } 469 }) 470 } 471 } 472} 473 474``` 475 476### on('statusChange')<sup>11+</sup> 477 478on(type: 'statusChange', callback: Callback<[DragAndDropInfo](#draganddropinfo11)>): void 479 480Subscribes to drag state changes. 481 482**Atomic service API**: This API can be used in atomic services since API version 12. 483 484**System capability**: SystemCapability.ArkUI.ArkUI.Full 485 486**Parameters** 487| Name | Type | Mandatory | Description | 488| ------ | ------ | ------- | ---------------- | 489| type | string | Yes | Event type. The value is fixed at **'statusChange'**, which indicates the drag state change event.| 490| callback | Callback<[DragAndDropInfo](#draganddropinfo11)> | Yes | Callback used to return a [DragAndDropInfo](#draganddropinfo11) instance.| 491 492**Example** 493 494> **NOTE** 495> 496> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 497 498```ts 499import { dragController } from "@kit.ArkUI"; 500import { unifiedDataChannel } from '@kit.ArkData'; 501 502@Entry 503@Component 504struct DragControllerPage { 505 build() { 506 Column() { 507 Button('touch to execute drag') 508 .onTouch((event?:TouchEvent) => { 509 let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 510 let text = new unifiedDataChannel.Text() 511 let unifiedData = new unifiedDataChannel.UnifiedData(text) 512 let dragInfo: dragController.DragInfo = { 513 pointerId: 0, 514 data: unifiedData, 515 extraParams: '' 516 } 517 try{ 518 let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo); // You are advised to use this.getUIContext().getDragController().createDragAction(). 519 if(!dragAction){ 520 console.info("listener dragAction is null"); 521 return 522 } 523 dragAction.on('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{ 524 console.info("Register to listen on drag status", JSON.stringify(dragAndDropInfo)); 525 }) 526 }catch(err) { 527 console.info("create dragAction Error:" + err.message); 528 } 529 }) 530 } 531 } 532} 533``` 534 535### off('statusChange')<sup>11+</sup> 536 537 off(type: 'statusChange', callback?: Callback<[DragAndDropInfo](#draganddropinfo11)>): void 538 539Unsubscribes from drag state changes. 540 541**Atomic service API**: This API can be used in atomic services since API version 12. 542 543**System capability**: SystemCapability.ArkUI.ArkUI.Full 544 545**Parameters** 546| Name | Type | Mandatory | Description | 547| ------ | ------ | ------- | ---------------- | 548| type | string | Yes | Event type. The value is fixed at **'statusChange'**, which indicates the drag state change event.| 549| callback | Callback<[DragAndDropInfo](#draganddropinfo11)> | No | Callback used to return a [DragAndDropInfo](#draganddropinfo11) instance. If this parameter is not set, this API unsubscribes from all callbacks corresponding to **type**.| 550 551**Example** 552 553> **NOTE** 554> 555> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 556 557```ts 558import { dragController } from "@kit.ArkUI" 559import { unifiedDataChannel } from '@kit.ArkData'; 560 561@Entry 562@Component 563struct DragControllerPage { 564 build() { 565 Column() { 566 Button('touch to execute drag') 567 .onTouch((event?:TouchEvent) => { 568 let customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 569 let text = new unifiedDataChannel.Text() 570 let unifiedData = new unifiedDataChannel.UnifiedData(text) 571 let dragInfo: dragController.DragInfo = { 572 pointerId: 0, 573 data: unifiedData, 574 extraParams: '' 575 } 576 try{ 577 let dragAction: dragController.DragAction | null = dragController.createDragAction(customBuilders, dragInfo); // You are advised to use this.getUIContext().getDragController().createDragAction(). 578 if(!dragAction){ 579 console.info("listener dragAction is null"); 580 return 581 } 582 dragAction.off('statusChange', (dragAndDropInfo: dragController.DragAndDropInfo)=>{ 583 console.info("Cancel listening on drag status", JSON.stringify(dragAndDropInfo)); 584 }) 585 }catch(err) { 586 console.info("create dragAction Error:" + err.message); 587 } 588 }) 589 } 590 } 591} 592``` 593 594## DragAndDropInfo<sup>11+</sup> 595 596**Atomic service API**: This API can be used in atomic services since API version 12. 597 598**System capability**: SystemCapability.ArkUI.ArkUI.Full 599 600Provides the data reported when the state changes during dragging. 601 602| Name | Type | Mandatory| Description | 603| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- | 604| status | [DragStatus](#dragstatus11) | Yes | Current dragging state (started or ended). | 605| event | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent) | Yes | Drag event corresponding to the current state. | 606| extraParams| string | No | Additional information about the drag action. Not supported currently.| 607 608## DragStatus<sup>11+</sup> 609 610**Atomic service API**: This API can be used in atomic services since API version 12. 611 612**System capability**: SystemCapability.ArkUI.ArkUI.Full 613 614Describes the dragging start and end states. 615 616| Name | Value | Description | 617| ----------- | ------------------------------------------------------| ---------------------------------------- | 618| STARTED | 0 | Dragging is started. | 619| ENDED | 1 | Dragging ends. | 620 621## AnimationOptions<sup>11+</sup> 622 623**Atomic service API**: This API can be used in atomic services since API version 12. 624 625**System capability**: SystemCapability.ArkUI.ArkUI.Full 626 627Defines the attributes required for initiating a drag action and information carried in the dragging process. 628 629| Name | Type | Mandatory| Description | 630| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- | 631| duration | number | No | Animation duration, in ms.<br>Default value: **1000**<br>**NOTE**<br>- If this parameter is set to a value less than 0, the value **0** is used.<br>- Floating-point values will be rounded down to integers. For example, if the value set is 1.2, **1** will be used.| 632| curve | [Curve](arkui-ts/ts-appendix-enums.md#curve) \| [ICurve](js-apis-curve.md#icurve9) | No | Animation curve.<br>Default value: **Curve.EaseInOut**| | 633 634## DragEventParam<sup>12+</sup> 635 636**Atomic service API**: This API can be used in atomic services since API version 12. 637 638**System capability**: SystemCapability.ArkUI.ArkUI.Full 639 640Represents the callback used to return the result after a drag ends. 641 642| Name | Type | Mandatory| Description | 643| ----------- | ------------------------------------------------------------ | ---- | ------------------------------ | 644| event | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent) | Yes | Drag event information that includes only the drag result.| 645| extraParams | string | Yes | Additional information about the drag event. | 646 647## dragController.getDragPreview<sup>11+</sup> 648 649getDragPreview(): DragPreview 650 651Obtains the **DragPreview** object, which represents the preview displayed during a drag. 652 653**Atomic service API**: This API can be used in atomic services since API version 12. 654 655**System capability**: SystemCapability.ArkUI.ArkUI.Full 656 657**Return value** 658 659| Type | Description | 660| ------------| ------------------------------------------------| 661| [DragPreview](#dragpreview11) | **DragPreview** object. It provides the API for setting the preview style. It does not work in the **OnDrop** and **OnDragEnd** callbacks.| 662 663**Example** 664 665For details, see [animate](#animate11). 666 667## DragPreview<sup>11+</sup> 668 669Implements a **DragPreview** object. This API does not work in the **OnDrop** and **OnDragEnd** callbacks. 670 671**Atomic service API**: This API can be used in atomic services since API version 12. 672 673**System capability**: SystemCapability.ArkUI.ArkUI.Full 674 675### setForegroundColor<sup>11+</sup> 676 677setForegroundColor(color: ResourceColor): void 678 679Sets the foreground color of the drag preview. This API does not work in the **OnDrop** and **OnDragEnd** callbacks. It can only be used on the object obtained through the [getDragPreview()](js-apis-arkui-UIContext.md#getdragpreview11) API. 680 681**Atomic service API**: This API can be used in atomic services since API version 12. 682 683**System capability**: SystemCapability.ArkUI.ArkUI.Full 684 685**Parameters** 686 687| Name | Type | Mandatory| Description | 688| -------- | -------------------------------- | ---- | ------------------------ | 689| color | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | Yes | Foreground color of the drag preview. | 690 691**Example** 692 693For details, see [animate](#animate11). 694 695 ### animate<sup>11+</sup> 696 697animate(options: AnimationOptions, handler: () => void): void 698 699Applies a foreground color animation to the drag preview. This API does not work in the **OnDrop** and **OnDragEnd** callbacks. It can only be used on the object obtained through the [getDragPreview()](js-apis-arkui-UIContext.md#getdragpreview11) API. 700 701**Atomic service API**: This API can be used in atomic services since API version 12. 702 703**System capability**: SystemCapability.ArkUI.ArkUI.Full 704 705**Parameters** 706 707| Name | Type | Mandatory| Description | 708| -------- | -------------------------------- | ---- | -----------------------------------| 709| options | [AnimationOptions](#animationoptions11) | Yes | Animation settings. | 710| handler | () => void | Yes | Callback used to change attributes such as the background mask color. | 711 712**Example** 713 714> **NOTE** 715> 716> You are advised to use the [getDragController](js-apis-arkui-UIContext.md#getdragcontroller11) API in [UIContext](js-apis-arkui-UIContext.md#uicontext) to obtain the **DragController** object associated with the current UI context. 717 7181. In the **EntryAbility.ets** file, obtain the UI context and save it to LocalStorage. 719 ```ts 720import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 721import { hilog } from '@kit.PerformanceAnalysisKit'; 722import { window, UIContext } from '@kit.ArkUI'; 723 724let uiContext: UIContext; 725let localStorage: LocalStorage = new LocalStorage('uiContext'); 726 727export default class EntryAbility extends UIAbility { 728 storage: LocalStorage = localStorage; 729 730 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 731 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 732 } 733 734 onDestroy(): void { 735 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); 736 } 737 738 onWindowStageCreate(windowStage: window.WindowStage): void { 739 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 740 741 windowStage.loadContent('pages/Index', (err, data) => { 742 if (err.code) { 743 hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 744 return; 745 } 746 hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 747 windowStage.getMainWindow((err, data) => { 748 if (err.code) { 749 hilog.error(0x0000, 'Failed to abtain the main window. Cause:' + err.message, ''); 750 return; 751 } 752 let windowClass: window.Window = data; 753 uiContext = windowClass.getUIContext(); 754 this.storage.setOrCreate<UIContext>('uiContext', uiContext); 755 }) 756 }); 757 } 758} 759 ``` 7602. In the **Index.ets** file, call **LocalStorage.getShared()** to obtain the UI context and then use the **DragController** object obtained to perform subsequent operations. 761 ```ts 762 763import { unifiedDataChannel } from '@kit.ArkData'; 764import { hilog } from '@kit.PerformanceAnalysisKit'; 765import { dragController, curves, promptAction, UIContext } from "@kit.ArkUI"; 766import { image } from '@kit.ImageKit'; 767import { BusinessError } from '@kit.BasicServicesKit'; 768 769let storages = LocalStorage.getShared(); 770 771@Entry(storages) 772@Component 773struct DragControllerPage { 774 @State pixmap: image.PixelMap|null = null 775 776 @Builder DraggingBuilder() { 777 Column() { 778 Text("DraggingBuilder") 779 .fontColor(Color.White) 780 .fontSize(12) 781 } 782 .width(100) 783 .height(100) 784 .backgroundColor(Color.Blue) 785 } 786 787 @Builder PixmapBuilder() { 788 Column() { 789 Text("PixmapBuilder") 790 } 791 .width(100) 792 .height(100) 793 .backgroundColor(Color.Blue) 794 } 795 796 build() { 797 Column() { 798 Button ('Drag Here') 799 .margin(10) 800 .onDragEnter(() => { 801 try { 802 let uiContext: UIContext = storages.get<UIContext>('uiContext') as UIContext; 803 let previewObj: dragController.DragPreview = uiContext.getDragController().getDragPreview(); 804 let foregroundColor: ResourceColor = Color.Green; 805 806 let previewAnimation: dragController.AnimationOptions = { 807 curve: curves.cubicBezierCurve(0.2,0,0,1), 808 } 809 previewObj.animate(previewAnimation, () => { 810 previewObj.setForegroundColor(foregroundColor); 811 }); 812 } catch (error) { 813 let msg = (error as BusinessError).message; 814 let code = (error as BusinessError).code; 815 hilog.error(0x0000, `show error code is ${code}, message is ${msg}`, ''); 816 } 817 }) 818 .onDrop(() => { 819 promptAction.showToast({duration: 100, message: 'Drag Success', bottom: 400}) 820 }) 821 Button ('Drag').onTouch ((event?:TouchEvent) => { 822 if(event){ 823 if (event.type == TouchType.Down) { 824 let text = new unifiedDataChannel.Text() 825 let unifiedData = new unifiedDataChannel.UnifiedData(text) 826 let dragInfo: dragController.DragInfo = { 827 pointerId: 0, 828 data: unifiedData, 829 extraParams: '' 830 } 831 class tmp{ 832 event:DragEvent|undefined = undefined 833 extraParams:string = '' 834 } 835 let eve:tmp = new tmp() 836 dragController.executeDrag(() => { // You are advised to use this.getUIContext().getDragController().executeDrag(). 837 this.DraggingBuilder() 838 }, dragInfo, (err , eve) => { 839 hilog.info(0x0000, `ljx ${JSON.stringify(err)}`, '') 840 if (eve && eve.event) { 841 if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) { 842 hilog.info(0x0000, 'success', ''); 843 } else if (eve.event.getResult() == DragResult.DRAG_FAILED) { 844 hilog.info(0x0000, 'failed', ''); 845 } 846 } 847 }) 848 } 849 } 850 }).margin({top:100}) 851 } 852 .width('100%') 853 .height('100%') 854 } 855} 856 ``` 857  858