• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# @ohos.arkui.dragController (DragController)
2
3本模块提供发起主动拖拽的能力,当应用接收到触摸或长按等事件时可以主动发起拖拽的动作,并在其中携带拖拽信息。
4
5> **说明:**
6>
7> 本模块首批接口从 API version 10 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
8> 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用,参见[UIContext](js-apis-arkui-UIContext.md#uicontext)说明。
9> 从API version 11开始,可以通过使用UIContext中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
10> 示例效果请以真机运行为准,当前 IDE 预览器不支持。
11
12## 导入模块
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
22主动发起拖拽能力,传入拖拽发起后跟手效果所拖拽的对象以及携带拖拽信息。通过回调返回结果。
23
24**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
25
26**系统能力:** SystemCapability.ArkUI.ArkUI.Full
27
28**参数:**
29
30| 参数名   | 类型                                                         | 必填 | 说明                                                         |
31| -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
32| custom   | [CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo说明) | 是   | 拖拽发起后跟手效果所拖拽的对象。<br/>**说明:** <br/>不支持全局builder。如果builder中使用了[Image](arkui-ts/ts-basic-components-image.md)组件,应尽量开启同步加载,即配置Image的[syncLoad](arkui-ts/ts-basic-components-image.md#syncload8)为true。该builder只用于生成当次拖拽中显示的图片,builder的修改不会同步到当前正在拖拽的图片,对builder的修改需要在下一次拖拽时生效。 |
33| dragInfo | [DragInfo](#draginfo)                                        | 是   | 拖拽信息。                                                   |
34| callback | [AsyncCallback](../apis-basic-services-kit/js-apis-base.md#asynccallback)&lt;[DragEventParam](#drageventparam12)&gt; | 是   | 拖拽结束返回结果的回调。                                     |
35
36**错误码:**
37
38以下错误码的详细介绍请参见[通用错误码](../errorcode-universal.md)错误码。
39
40| 错误码ID | 错误信息      |
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**示例:**
46
47> **说明:**
48>
49> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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) => { // 建议使用 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  ![zh-cn_executeDrag1](figures/executeDrag1.gif)
124## dragController.executeDrag
125
126executeDrag(custom: CustomBuilder | DragItemInfo, dragInfo: DragInfo): Promise\<DragEventParam>
127
128主动发起拖拽能力,传入拖拽发起后跟手效果所拖拽的对象以及携带拖拽信息。通过Promise返回结果。
129
130**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
131
132**系统能力:** SystemCapability.ArkUI.ArkUI.Full
133
134**参数:**
135
136| 参数名   | 类型                                                         | 必填 | 说明                             |
137| -------- | ------------------------------------------------------------ | ---- | -------------------------------- |
138| custom   | [CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo说明) | 是   | 拖拽发起后跟手效果所拖拽的对象。 |
139| dragInfo | [DragInfo](#draginfo)                                        | 是   | 拖拽信息。                       |
140
141**返回值:**
142
143| 类型                                               | 说明                     |
144| -------------------------------------------------- | ------------------------ |
145| Promise&lt;[DragEventParam](#drageventparam12)&gt; | 拖拽结束返回结果的回调。 |
146
147**错误码:**
148以下错误码的详细介绍请参见[通用错误码](../errorcode-universal.md)错误码。
149| 错误码ID | 错误信息      |
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**示例:**
155
156> **说明:**
157>
158> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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) // 建议使用 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  ![zh-cn_executeDrag2](figures/executeDrag2.gif)
261## DragInfo
262
263**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
264
265**系统能力:** SystemCapability.ArkUI.ArkUI.Full
266
267发起拖拽所需要的属性和拖拽时携带的信息。
268
269| 名称        | 类型                                                   | 必填 | 说明                                     |
270| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- |
271| pointerId   | number                                                 | 是   | 设置启动拖拽时屏幕上触摸点的Id。取值范围为0-9的整数。         |
272| data        | [unifiedDataChannel.UnifiedData](../apis-arkdata/js-apis-data-unifiedDataChannel.md#unifieddata) | 否   | 设置拖拽过程中携带的数据。               |
273| extraParams | string                                                 | 否   | 设置拖拽事件额外信息,具体功能暂未实现。默认值为空。 |
274| touchPoint<sup>11+</sup>    | [TouchPoint](arkui-ts/ts-types.md#touchpoint11)  | 否   | 配置跟手点坐标。不配置时,左右居中,顶部向下偏移20%。 |
275| previewOptions<sup>11+</sup>| [DragPreviewOptions](arkui-ts/ts-universal-attributes-drag-drop.md#dragpreviewoptions11)                                | 否   | 设置拖拽过程中背板图处理模式及数量角标的显示。 |
276
277## dragController.createDragAction<sup>11+</sup>
278
279createDragAction(customArray: Array&lt;CustomBuilder \| DragItemInfo&gt;, dragInfo: DragInfo): DragAction
280
281创建拖拽的Action对象,需要显式指定拖拽背板图(可多个),以及拖拽的数据,跟手点等信息;当通过一个已创建的 Action 对象发起的拖拽未结束时,无法再次创建新的 Action 对象,接口会抛出异常;当Action对象的生命周期结束后,注册在该对象上的回调函数会失效,因此需要在一个尽量长的作用域下持有该对象,并在每次发起拖拽前通过createDragAction返回新的对象覆盖旧值。
282
283**说明:** 建议控制传递的拖拽背板数量,传递过多容易导致拖起的效率问题。
284
285**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
286
287**系统能力:** SystemCapability.ArkUI.ArkUI.Full
288
289**参数:**
290
291| 参数名   | 类型                                                         | 必填 | 说明                             |
292| --------      | ------------------------------------------------------------ | ---- | -------------------------------- |
293| customArray  | Array&lt;[CustomBuilder](arkui-ts/ts-types.md#custombuilder8) \| [DragItemInfo](arkui-ts/ts-universal-events-drag-drop.md#dragiteminfo说明)&gt; | 是   | 拖拽发起后跟手效果所拖拽的对象。 |
294| dragInfo | [DragInfo](#draginfo)                                        | 是   | 拖拽信息。                       |
295
296**返回值:**
297
298| 类型                                                   | 说明               |
299| ------------------------------------------------------ | ------------------ |
300| [DragAction](#dragaction11)| 创建拖拽Action对象,主要用于后面实现注册监听拖拽状态改变事件和启动拖拽服务。 |
301
302**错误码:**
303
304以下错误码的详细介绍请参见[通用错误码](../errorcode-universal.md)错误码。
305| 错误码ID | 错误信息      |
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**示例:**
311
312> **说明:**
313>
314> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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('多对象dragAction customBuilder拖拽').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) // 建议使用 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  ![zh-cn_executeDrag3](figures/executeDrag3.gif)
408## DragAction<sup>11+</sup>
409
410监听状态改变,启动拖拽服务的对象。
411
412**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
413
414**系统能力:** SystemCapability.ArkUI.ArkUI.Full
415
416### startDrag<sup>11+</sup>
417
418startDrag(): Promise&lt;void&gt;
419
420启动拖拽服务,返回Promise对象,回调启动成功和失败的结果。
421
422**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
423
424**系统能力:** SystemCapability.ArkUI.ArkUI.Full
425
426**错误码:**
427
428| 错误码ID | 错误信息      |
429| -------- | ------------- |
430| 100001   | Internal handling failed. |
431
432**示例:**
433
434> **说明:**
435>
436> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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 execute 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) // 建议使用 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
497注册监听拖拽状态改变事件。
498
499**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
500
501**系统能力:** SystemCapability.ArkUI.ArkUI.Full
502
503**参数:**
504| 参数名     | 类型  | 必填    | 说明             |
505| ------ | ------ | ------- | ---------------- |
506|  type  | string | 是      | 监听事件,固定为'statusChange',即注册监听拖拽状态改变事件。|
507|  callback  | Callback&lt;[DragAndDropInfo](#draganddropinfo11)&gt; | 是      | 回调函数,返回当前的[DragAndDropInfo](#draganddropinfo11)组件状态。|
508
509**示例:**
510
511> **说明:**
512>
513> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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 execute 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) // 建议使用 this.getUIContext().getDragController().createDragAction()接口
555              if(!this.dragAction){
556                console.info("listener dragAction is null");
557                return;
558              }
559              // 监听状态改变,触发后打印func中的日志
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
579取消注册监听拖拽状态改变事件。
580
581**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
582
583**系统能力:** SystemCapability.ArkUI.ArkUI.Full
584
585**参数:**
586| 参数名     | 类型  | 必填    | 说明             |
587| ------ | ------ | ------- | ---------------- |
588|  type  | string | 是      | 监听事件,固定为'statusChange',即取消监听拖拽状态改变事件。|
589|  callback  | Callback&lt;[DragAndDropInfo](#draganddropinfo11)&gt; | 否      | 回调函数,取消注册了该回调函数的事件, 不设置取消所有监听。|
590
591**示例:**
592
593> **说明:**
594>
595> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
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) // 建议使用 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              // 取消监听,发起拖拽后不会打印func中的日志
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**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
661
662**系统能力:** SystemCapability.ArkUI.ArkUI.Full
663
664拖拽过程中监听到status改变时上报的数据。
665
666| 名称          | 类型                                                   | 必填 | 说明                                     |
667| -----------   | ------------------------------------------------------ | ---- | ---------------------------------------- |
668| status       | [DragStatus](#dragstatus11)                                                 | 是   | 当前拖拽状态(启动和结束)。         |
669| event        | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent) | 是   | 当前状态所对应的拖拽事件。通过dragController发起的dragEvent仅支持获取result和behavior,且用于拖拽结束状态。 |
670| extraParams| string                                                 | 否   | 设置拖拽事件额外信息,具体功能暂未实现。默认值为空。 |
671
672## DragStatus<sup>11+</sup>
673
674**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
675
676**系统能力:** SystemCapability.ArkUI.ArkUI.Full
677
678拖拽开始和结束状态。
679
680| 名称          | 值                                                   | 说明                                     |
681| -----------   | ------------------------------------------------------| ---------------------------------------- |
682| STARTED       | 0                                                  | 拖拽已成功发起。         |
683| ENDED        | 1                                                  | 拖拽结束。               |
684
685## AnimationOptions<sup>11+</sup>
686
687**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
688
689**系统能力:** SystemCapability.ArkUI.ArkUI.Full
690
691发起拖拽所需要的属性和拖拽时携带的信息。
692
693| 名称        | 类型                                                   | 必填 | 说明                                     |
694| ----------- | ------------------------------------------------------ | ---- | ---------------------------------------- |
695| duration    | number                                                 | 否   | 动画持续时间,单位为毫秒。<br/>默认值:1000<br/>**说明:**<br/>-&nbsp;设置小于0的值时按0处理。<br/>-&nbsp;设置浮点型类型的值时,向下取整。例如,设置值为1.2,按照1处理。|
696| curve       |&nbsp;[Curve](arkui-ts/ts-appendix-enums.md#curve)&nbsp;\|&nbsp;[ICurve](js-apis-curve.md#icurve) | 否    | 设置动画曲线。<br/>默认值:Curve.EaseInOut|                          |
697
698## DragEventParam<sup>12+</sup>
699
700**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
701
702**系统能力:** SystemCapability.ArkUI.ArkUI.Full
703
704拖拽结束返回结果的回调。
705
706| 名称        | 类型                                                         | 必填 | 说明                           |
707| ----------- | ------------------------------------------------------------ | ---- | ------------------------------ |
708| event       | [DragEvent](arkui-ts/ts-universal-events-drag-drop.md#dragevent) | 是   | 拖拽事件信息,仅包括拖拽结果。 |
709| extraParams | string                                                       | 是   | 拖拽事件额外信息。             |
710
711## dragController.getDragPreview<sup>11+</sup>
712
713getDragPreview(): DragPreview
714
715返回一个代表拖拽背板的对象。
716
717**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
718
719**系统能力:** SystemCapability.ArkUI.ArkUI.Full
720
721**返回值:**
722
723| 类型        | 说明                                            |
724| ------------| ------------------------------------------------|
725| [DragPreview](#dragpreview11) | 一个代表拖拽背板的对象,提供背板样式设置的接口,在OnDrop和OnDragEnd回调中使用不生效。 |
726
727**示例:**
728
729请参考[animate](#animate11)
730
731## DragPreview<sup>11+</sup>
732
733拖拽背板的对象,在OnDrop和OnDragEnd回调中使用不生效。
734
735**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
736
737**系统能力:** SystemCapability.ArkUI.ArkUI.Full
738
739### setForegroundColor<sup>11+</sup>
740
741setForegroundColor(color: ResourceColor): void
742
743设置背板蒙版颜色,在OnDrop和OnDragEnd回调中使用不生效,仅支持通过 [getDragPreview()](js-apis-arkui-UIContext.md#getdragpreview11) 方法获取到的对象上使用。
744
745**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
746
747**系统能力:** SystemCapability.ArkUI.ArkUI.Full
748
749**参数:**
750
751| 参数名   | 类型                             | 必填 | 说明                     |
752| -------- | -------------------------------- | ---- | ------------------------ |
753| color    | [ResourceColor](arkui-ts/ts-types.md#resourcecolor) | 是   |      背板蒙版颜色。                    |
754
755**示例:**
756
757请参考[animate](#animate11)
758
759  ### animate<sup>11+</sup>
760
761animate(options: AnimationOptions, handler: () => void): void
762
763设置背板蒙版颜色变化动效,在OnDrop和OnDragEnd回调中使用不生效,仅支持通过 [getDragPreview()](js-apis-arkui-UIContext.md#getdragpreview11) 方法获取到的对象上使用。
764
765**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
766
767**系统能力:** SystemCapability.ArkUI.ArkUI.Full
768
769**参数:**
770
771| 参数名   | 类型                             | 必填 | 说明                               |
772| -------- | -------------------------------- | ---- | -----------------------------------|
773| options  | [AnimationOptions](#animationoptions11)                | 是   | 动效参数。                           |
774| handler  | () => void                         | 是   | 用于修改背板蒙版颜色等属性的回调方法。  |
775
776**示例:**
777
778> **说明:**
779>
780> 推荐通过使用[UIContext](js-apis-arkui-UIContext.md#uicontext)中的[getDragController](js-apis-arkui-UIContext.md#getdragcontroller11)方法获取当前UI上下文关联的DragController对象。
781
7821.在EntryAbility.ets中获取UI上下文并保存至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.在Index.ets中通过LocalStorage.getShared()获取UI上下文,进而获取DragController对象实施后续操作。
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('拖拽至此处')
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('拖起').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(() => { // 建议使用 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  ![zh-cn_executeDrag5](figures/executeDrag5.gif)