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