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. The value is an integer ranging from 0 to 9. | 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. The default value is null.| 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 horizontally and shifted downward by 20% from the top.| 275| previewOptions<sup>11+</sup>| [DragPreviewOptions](arkui-ts/ts-universal-attributes-drag-drop.md#dragpreviewoptions11) | No | Processing mode of the drag preview and the display of the number badge during dragging.| 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, componentSnapshot } from "@kit.ArkUI"; 440import { unifiedDataChannel } from '@kit.ArkData'; 441 442@Entry 443@Component 444struct DragControllerPage { 445 private dragAction: dragController.DragAction | null = null; 446 customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 447 @Builder DraggingBuilder() { 448 Column() { 449 Text("DraggingBuilder") 450 .fontColor(Color.White) 451 .fontSize(12) 452 } 453 .width(100) 454 .height(100) 455 .backgroundColor(Color.Blue) 456 } 457 458 build() { 459 Column() { 460 Button('Touch to Drag').onTouch((event?:TouchEvent) => { 461 if(event){ 462 if (event.type == TouchType.Down) { 463 this.customBuilders.splice(0, this.customBuilders.length); 464 this.customBuilders.push(()=>{this.DraggingBuilder()}); 465 let text = new unifiedDataChannel.PlainText() 466 text.textContent = 'drag text' 467 let unifiedData = new unifiedDataChannel.UnifiedData(text) 468 let dragInfo: dragController.DragInfo = { 469 pointerId: 0, 470 data: unifiedData, 471 extraParams: '' 472 } 473 try{ 474 this.dragAction = dragController.createDragAction(this.customBuilders, dragInfo) // You are advised to use this.getUIContext().getDragController().createDragAction(). 475 if(!this.dragAction){ 476 console.info("listener dragAction is null"); 477 return; 478 } 479 this.dragAction.startDrag().then(()=>{}).catch((err:Error)=>{ 480 console.info("start drag Error:" + err.message); 481 }) 482 } catch(err) { 483 console.info("create dragAction Error:" + err.message); 484 } 485 } 486 } 487 }).margin({top:20}) 488 } 489 } 490} 491``` 492 493### on('statusChange')<sup>11+</sup> 494 495on(type: 'statusChange', callback: Callback<[DragAndDropInfo](#draganddropinfo11)>): void 496 497Subscribes to drag state changes. 498 499**Atomic service API**: This API can be used in atomic services since API version 12. 500 501**System capability**: SystemCapability.ArkUI.ArkUI.Full 502 503**Parameters** 504| Name | Type | Mandatory | Description | 505| ------ | ------ | ------- | ---------------- | 506| type | string | Yes | Event type. The value is fixed at **'statusChange'**, which indicates the drag state change event.| 507| callback | Callback<[DragAndDropInfo](#draganddropinfo11)> | Yes | Callback used to return a [DragAndDropInfo](#draganddropinfo11) instance.| 508 509**Example** 510 511> **NOTE** 512> 513> 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. 514 515```ts 516import { dragController, componentSnapshot } from "@kit.ArkUI"; 517import { unifiedDataChannel } from '@kit.ArkData'; 518 519@Entry 520@Component 521struct DragControllerPage { 522 private dragAction: dragController.DragAction | null = null; 523 customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 524 @Builder DraggingBuilder() { 525 Column() { 526 Text("DraggingBuilder") 527 .fontColor(Color.White) 528 .fontSize(12) 529 } 530 .width(100) 531 .height(100) 532 .backgroundColor(Color.Blue) 533 } 534 535 build() { 536 Column() { 537 Button('Touch to Drag').onTouch((event?:TouchEvent) => { 538 if(event){ 539 if (event.type == TouchType.Down) { 540 this.customBuilders.splice(0, this.customBuilders.length); 541 this.customBuilders.push(()=>{this.DraggingBuilder()}); 542 let text = new unifiedDataChannel.PlainText() 543 text.textContent = 'drag text' 544 let unifiedData = new unifiedDataChannel.UnifiedData(text) 545 let dragInfo: dragController.DragInfo = { 546 pointerId: 0, 547 data: unifiedData, 548 extraParams: '' 549 } 550 let func = (dragAndDropInfo: dragController.DragAndDropInfo) => { 551 console.info("Register to listen on drag status", JSON.stringify(dragAndDropInfo)); 552 } 553 try{ 554 this.dragAction = dragController.createDragAction(this.customBuilders, dragInfo) // You are advised to use this.getUIContext().getDragController().createDragAction(). 555 if(!this.dragAction){ 556 console.info("listener dragAction is null"); 557 return; 558 } 559 // Subscribe to drag state changes. The information in func will be logged once a change is detected. 560 this.dragAction.on('statusChange', func); 561 this.dragAction.startDrag().then(()=>{}).catch((err:Error)=>{ 562 console.info("start drag Error:" + err.message); 563 }) 564 } catch(err) { 565 console.info("create dragAction Error:" + err.message); 566 } 567 } 568 } 569 }).margin({top:20}) 570 } 571 } 572} 573``` 574 575### off('statusChange')<sup>11+</sup> 576 577 off(type: 'statusChange', callback?: Callback<[DragAndDropInfo](#draganddropinfo11)>): void 578 579Unsubscribes from drag state changes. 580 581**Atomic service API**: This API can be used in atomic services since API version 12. 582 583**System capability**: SystemCapability.ArkUI.ArkUI.Full 584 585**Parameters** 586| Name | Type | Mandatory | Description | 587| ------ | ------ | ------- | ---------------- | 588| type | string | Yes | Event type. The value is fixed at **'statusChange'**, which indicates the drag state change event.| 589| callback | Callback<[DragAndDropInfo](#draganddropinfo11)> | No | Callback to unregister. If this parameter is not specified, this API unregisters all callbacks for the specified event.| 590 591**Example** 592 593> **NOTE** 594> 595> 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. 596 597```ts 598import { dragController, componentSnapshot } from "@kit.ArkUI"; 599import { unifiedDataChannel } from '@kit.ArkData'; 600 601@Entry 602@Component 603struct DragControllerPage { 604 private dragAction: dragController.DragAction | null = null; 605 customBuilders:Array<CustomBuilder | DragItemInfo> = new Array<CustomBuilder | DragItemInfo>(); 606 @Builder DraggingBuilder() { 607 Column() { 608 Text("DraggingBuilder") 609 .fontColor(Color.White) 610 .fontSize(12) 611 } 612 .width(100) 613 .height(100) 614 .backgroundColor(Color.Blue) 615 } 616 617 build() { 618 Column() { 619 Button('touch to execute drag').onTouch((event?:TouchEvent) => { 620 if(event){ 621 if (event.type == TouchType.Down) { 622 this.customBuilders.splice(0, this.customBuilders.length); 623 this.customBuilders.push(()=>{this.DraggingBuilder()}); 624 let text = new unifiedDataChannel.PlainText() 625 text.textContent = 'drag text' 626 let unifiedData = new unifiedDataChannel.UnifiedData(text) 627 let dragInfo: dragController.DragInfo = { 628 pointerId: 0, 629 data: unifiedData, 630 extraParams: '' 631 } 632 let func = (dragAndDropInfo: dragController.DragAndDropInfo) => { 633 console.info("Register to listen on drag status", JSON.stringify(dragAndDropInfo)); 634 } 635 try{ 636 this.dragAction = dragController.createDragAction(this.customBuilders, dragInfo) // You are advised to use this.getUIContext().getDragController().createDragAction(). 637 if(!this.dragAction){ 638 console.info("listener dragAction is null"); 639 return; 640 } 641 this.dragAction.on('statusChange', func); 642 // Unsubscribe from drag state changes. The information in func will not be logged after a drag operation starts. 643 this.dragAction.off('statusChange', func); 644 this.dragAction.startDrag().then(()=>{}).catch((err:Error)=>{ 645 console.info("start drag Error:" + err.message); 646 }) 647 } catch(err) { 648 console.info("create dragAction Error:" + err.message); 649 } 650 } 651 } 652 }).margin({top:20}) 653 } 654 } 655} 656``` 657 658## DragAndDropInfo<sup>11+</sup> 659 660**Atomic service API**: This API can be used in atomic services since API version 12. 661 662**System capability**: SystemCapability.ArkUI.ArkUI.Full 663 664Provides the data reported when the state changes during dragging. 665 666| Name | Type | Mandatory| Description | 667| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- | 668| status | [DragStatus](#dragstatus11) | Yes | Current dragging state (started or ended). | 669| event | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent7) | Yes | Drag event corresponding to the current state. The drag event initiated by **dragController** only supports the APIs for obtaining the result and behavior, and is used exclusively for the dragging end state.| 670| extraParams| string | No | Additional information about the drag action. Not supported currently. The default value is null.| 671 672## DragStatus<sup>11+</sup> 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 678Describes the dragging start and end states. 679 680| Name | Value | Description | 681| ----------- | ------------------------------------------------------| ---------------------------------------- | 682| STARTED | 0 | Dragging is started. | 683| ENDED | 1 | Dragging ends. | 684 685## AnimationOptions<sup>11+</sup> 686 687**Atomic service API**: This API can be used in atomic services since API version 12. 688 689**System capability**: SystemCapability.ArkUI.ArkUI.Full 690 691Defines the attributes required for initiating a drag action and information carried in the dragging process. 692 693| Name | Type | Mandatory| Description | 694| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- | 695| 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.| 696| curve | [Curve](arkui-ts/ts-appendix-enums.md#curve) \| [ICurve](js-apis-curve.md#icurve9) | No | Animation curve.<br>Default value: **Curve.EaseInOut**| | 697 698## DragEventParam<sup>12+</sup> 699 700**Atomic service API**: This API can be used in atomic services since API version 12. 701 702**System capability**: SystemCapability.ArkUI.ArkUI.Full 703 704Represents the callback used to return the result after a drag ends. 705 706| Name | Type | Mandatory| Description | 707| ----------- | ------------------------------------------------------------ | ---- | ------------------------------ | 708| event | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent7) | Yes | Drag event information that includes only the drag result.| 709| extraParams | string | Yes | Additional information about the drag event. | 710 711## dragController.getDragPreview<sup>11+</sup> 712 713getDragPreview(): DragPreview 714 715Obtains the **DragPreview** object, which represents the preview displayed during a drag operation. 716 717**Atomic service API**: This API can be used in atomic services since API version 12. 718 719**System capability**: SystemCapability.ArkUI.ArkUI.Full 720 721**Return value** 722 723| Type | Description | 724| ------------| ------------------------------------------------| 725| [DragPreview](#dragpreview11) | **DragPreview** object. It provides the API for setting the preview style. It does not work in the **OnDrop** and **OnDragEnd** callbacks.| 726 727**Example** 728 729For details, see [animate](#animate11). 730 731## DragPreview<sup>11+</sup> 732 733Implements a **DragPreview** object. This API does not work in the **OnDrop** and **OnDragEnd** callbacks. 734 735**Atomic service API**: This API can be used in atomic services since API version 12. 736 737**System capability**: SystemCapability.ArkUI.ArkUI.Full 738 739### setForegroundColor<sup>11+</sup> 740 741setForegroundColor(color: ResourceColor): void 742 743Sets 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. 744 745**Atomic service API**: This API can be used in atomic services since API version 12. 746 747**System capability**: SystemCapability.ArkUI.ArkUI.Full 748 749**Parameters** 750 751| Name | Type | Mandatory| Description | 752| -------- | -------------------------------- | ---- | ------------------------ | 753| color | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | Yes | Foreground color of the drag preview. | 754 755**Example** 756 757For details, see [animate](#animate11). 758 759 ### animate<sup>11+</sup> 760 761animate(options: AnimationOptions, handler: () => void): void 762 763Applies 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. 764 765**Atomic service API**: This API can be used in atomic services since API version 12. 766 767**System capability**: SystemCapability.ArkUI.ArkUI.Full 768 769**Parameters** 770 771| Name | Type | Mandatory| Description | 772| -------- | -------------------------------- | ---- | -----------------------------------| 773| options | [AnimationOptions](#animationoptions11) | Yes | Animation settings. | 774| handler | () => void | Yes | Callback used to change attributes such as the background mask color. | 775 776**Example** 777 778> **NOTE** 779> 780> 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. 781 7821. In the **EntryAbility.ets** file, obtain the UI context and save it to LocalStorage. 783 ```ts 784import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 785import { hilog } from '@kit.PerformanceAnalysisKit'; 786import { window, UIContext } from '@kit.ArkUI'; 787 788let uiContext: UIContext; 789let localStorage: LocalStorage = new LocalStorage('uiContext'); 790 791export default class EntryAbility extends UIAbility { 792 storage: LocalStorage = localStorage; 793 794 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 795 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 796 } 797 798 onDestroy(): void { 799 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); 800 } 801 802 onWindowStageCreate(windowStage: window.WindowStage): void { 803 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 804 805 windowStage.loadContent('pages/Index', (err, data) => { 806 if (err.code) { 807 hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 808 return; 809 } 810 hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); 811 windowStage.getMainWindow((err, data) => { 812 if (err.code) { 813 hilog.error(0x0000, 'Failed to abtain the main window. Cause:' + err.message, ''); 814 return; 815 } 816 let windowClass: window.Window = data; 817 uiContext = windowClass.getUIContext(); 818 this.storage.setOrCreate<UIContext>('uiContext', uiContext); 819 }) 820 }); 821 } 822} 823 ``` 8242. In the **Index.ets** file, call **LocalStorage.getShared()** to obtain the UI context and then use the **DragController** object obtained to perform subsequent operations. 825 ```ts 826 827import { unifiedDataChannel } from '@kit.ArkData'; 828import { hilog } from '@kit.PerformanceAnalysisKit'; 829import { dragController, curves, promptAction, UIContext } from "@kit.ArkUI"; 830import { image } from '@kit.ImageKit'; 831import { BusinessError } from '@kit.BasicServicesKit'; 832 833let storages = LocalStorage.getShared(); 834 835@Entry(storages) 836@Component 837struct DragControllerPage { 838 @State pixmap: image.PixelMap|null = null 839 840 @Builder DraggingBuilder() { 841 Column() { 842 Text("DraggingBuilder") 843 .fontColor(Color.White) 844 .fontSize(12) 845 } 846 .width(100) 847 .height(100) 848 .backgroundColor(Color.Blue) 849 } 850 851 @Builder PixmapBuilder() { 852 Column() { 853 Text("PixmapBuilder") 854 } 855 .width(100) 856 .height(100) 857 .backgroundColor(Color.Blue) 858 } 859 860 build() { 861 Column() { 862 Button('Drag Here') 863 .margin(10) 864 .onDragEnter(() => { 865 try { 866 let uiContext: UIContext = storages.get<UIContext>('uiContext') as UIContext; 867 let previewObj: dragController.DragPreview = uiContext.getDragController().getDragPreview(); 868 let foregroundColor: ResourceColor = Color.Green; 869 870 let previewAnimation: dragController.AnimationOptions = { 871 curve: curves.cubicBezierCurve(0.2,0,0,1), 872 } 873 previewObj.animate(previewAnimation, () => { 874 previewObj.setForegroundColor(foregroundColor); 875 }); 876 } catch (error) { 877 let msg = (error as BusinessError).message; 878 let code = (error as BusinessError).code; 879 hilog.error(0x0000, `show error code is ${code}, message is ${msg}`, ''); 880 } 881 }) 882 .onDrop(() => { 883 promptAction.showToast({duration: 100, message: 'Drag Success', bottom: 400}) 884 }) 885 Button('Drag').onTouch((event?:TouchEvent) => { 886 if(event){ 887 if (event.type == TouchType.Down) { 888 let text = new unifiedDataChannel.Text() 889 let unifiedData = new unifiedDataChannel.UnifiedData(text) 890 let dragInfo: dragController.DragInfo = { 891 pointerId: 0, 892 data: unifiedData, 893 extraParams: '' 894 } 895 class tmp{ 896 event:DragEvent|undefined = undefined 897 extraParams:string = '' 898 } 899 let eve:tmp = new tmp() 900 dragController.executeDrag(() => { // You are advised to use this.getUIContext().getDragController().executeDrag(). 901 this.DraggingBuilder() 902 }, dragInfo, (err , eve) => { 903 hilog.info(0x0000, `ljx ${JSON.stringify(err)}`, '') 904 if (eve && eve.event) { 905 if (eve.event.getResult() == DragResult.DRAG_SUCCESSFUL) { 906 hilog.info(0x0000, 'success', ''); 907 } else if (eve.event.getResult() == DragResult.DRAG_FAILED) { 908 hilog.info(0x0000, 'failed', ''); 909 } 910 } 911 }) 912 } 913 } 914 }).margin({top:100}) 915 } 916 .width('100%') 917 .height('100%') 918 } 919} 920 ``` 921  922 923## DragStartRequestStatus<sup>18+</sup> 924 925Enumerates the states defining whether an application can initiate a drag operation. 926 927**Atomic service API**: This API can be used in atomic services since API version 18. 928 929**System capability**: SystemCapability.ArkUI.ArkUI.Full 930 931| Name | Value| Description | 932| -------- | -- | ------------------------------------------------------------ | 933| WAITING | 0 | The application is preparing data and cannot initiate a drag operation yet.| 934| READY | 1 | The application has completed data preparation and is ready to initiate a drag operation.| 935