• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)&lt;[DragEventParam](#drageventparam12)&gt; | 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  ![en-us_executeDrag1](figures/executeDrag1.gif)
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&lt;[DragEventParam](#drageventparam12)&gt; | 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  ![en-us_executeDrag2](figures/executeDrag2.gif)
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&lt;CustomBuilder \| DragItemInfo&gt;, 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&lt;[CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo)&gt; | 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  ![en-us_executeDrag3](figures/executeDrag3.gif)
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&lt;void&gt;
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&lt;[DragAndDropInfo](#draganddropinfo11)&gt;): 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&lt;[DragAndDropInfo](#draganddropinfo11)&gt; | 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&lt;[DragAndDropInfo](#draganddropinfo11)&gt;): 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&lt;[DragAndDropInfo](#draganddropinfo11)&gt; | 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  ![en-us_executeDrag5](figures/executeDrag5.gif)
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