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