• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 拖拽事件
2
3拖拽事件是指在用户界面中,当用户拖动某个对象(如文件、控件或元素)时触发的一系列事件。这些事件允许开发者自定义拖拽行为,实现诸如拖放、调整位置等功能。
4
5>  **说明:**
6>
7>  从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8>
9> 应用本身预置的资源文件(即应用在安装前的HAP包中已经存在的资源文件)仅支持本地应用内拖拽。
10
11ArkUI框架对以下组件实现了默认的拖拽能力,支持对数据的拖出或拖入响应。开发者也可以通过实现通用拖拽事件来自定义拖拽响应。
12
13- 默认支持拖出能力的组件(可从组件上拖出数据):[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[RichEditor](ts-basic-components-richeditor.md)、[Text](ts-basic-components-text.md)、[Image](ts-basic-components-image.md)、<!--Del-->[FormComponent](ts-basic-components-formcomponent-sys.md)、<!--DelEnd-->[Hyperlink](ts-container-hyperlink.md),开发者可通过设置这些组件的[draggable](ts-universal-attributes-drag-drop.md#draggable)属性来控制对默认拖拽能力的使用。
14
15- 默认支持拖入能力的组件(目标组件可响应拖入数据):[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[RichEditor](ts-basic-components-richeditor.md),开发者可通过设置这些组件的[allowDrop](ts-universal-attributes-drag-drop.md#allowdrop)属性为null来禁用对默认拖入能力的支持。
16
17<!--RP1--><!--RP1End-->其他组件需要开发者将draggable属性设置为true,并在onDragStart等接口中实现数据传输相关内容,才能正确处理拖拽。
18
19> **说明:**
20>
21> Text组件需配合[copyOption](ts-basic-components-text.md#copyoption9)一起使用,设置copyOptions为CopyOptions.InApp或者CopyOptions.LocalDevice22
23## onDragStart
24
25onDragStart(event: (event: DragEvent, extraParams?: string) => CustomBuilder | DragItemInfo)
26
27第一次拖拽此事件绑定的组件时,长按时间 >= 500ms,然后手指移动距离 >= 10vp,触发回调。
28
29针对默认支持拖出能力的组件,如果开发者设置了onDragStart,优先执行开发者的onDragStart,并根据执行情况决定是否使用系统默认的拖出能力,具体为:
30- 如果开发者返回了自定义背板图,则不再使用系统默认的拖拽背板图;
31- 如果开发者设置了拖拽数据,则不再使用系统默认填充的拖拽数据。
32
33文本类组件[Text](ts-basic-components-text.md)、[Search](ts-basic-components-search.md)、[TextInput](ts-basic-components-textinput.md)、[TextArea](ts-basic-components-textarea.md)、[RichEditor](ts-basic-components-richeditor.md)对选中的文本内容进行拖拽时,不支持背板图的自定义。当onDragStart与菜单预览一起使用或使用了默认支持拖出能力的组件时,预览及菜单项上的自定义内容不支持拖拽。
34
35**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
36
37**事件优先级:** 长按触发时间 < 500ms,长按事件优先拖拽事件响应,长按触发时间 >= 500ms,拖拽事件优先长按事件响应。
38
39**系统能力:** SystemCapability.ArkUI.ArkUI.Full
40
41**参数:**
42
43| 参数名      | 类型                            | 必填 | 说明               |
44| ----------- | ------------------------------- | ---- | ------------------ |
45| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => [CustomBuilder](ts-types.md#custombuilder8) &nbsp;\|&nbsp; [DragItemInfo](#dragiteminfo说明)  | 是   | 回调函数。<br/> **说明:**<br/> event为拖拽事件信息。<br/> extraParams为拖拽事件额外信息。需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
46
47**返回值:**
48
49| 类型                                                         | 说明                     |
50| ------------------------------------------------------------ | ------------------------ |
51| [CustomBuilder](ts-types.md#custombuilder8)&nbsp;\|&nbsp;[DragItemInfo](#dragiteminfo说明) | 拽过程中显示的组件信息。<br/>**说明:** 不支持全局builder。 |
52
53## onDragEnter
54
55onDragEnter(event: (event: DragEvent, extraParams?: string) => void)
56
57拖拽进入组件范围内时,触发回调,当监听了[onDrop](#ondrop)事件时,此事件才有效。
58
59**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
60
61**系统能力:** SystemCapability.ArkUI.ArkUI.Full
62
63**参数:**
64
65| 参数名      | 类型                            | 必填 | 说明                           |
66| ----------- | ------------------------------- | ---- | ------------------------------ |
67| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
68
69## onDragMove
70
71onDragMove(event: (event: DragEvent, extraParams?: string) => void)
72
73拖拽在组件范围内移动时,触发回调,当监听了[onDrop](#ondrop)事件时,此事件才有效。
74
75**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
76
77**系统能力:** SystemCapability.ArkUI.ArkUI.Full
78
79**参数:**
80
81| 参数名      | 类型                            | 必填 | 说明                           |
82| ----------- | ------------------------------- | ---- | ------------------------------ |
83| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
84
85## onDragLeave
86
87onDragLeave(event: (event: DragEvent, extraParams?: string) => void)
88
89拖拽离开组件范围内时,触发回调,当监听了[onDrop](#ondrop)事件时,此事件才有效。
90
91**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
92
93**系统能力:** SystemCapability.ArkUI.ArkUI.Full
94
95**参数:**
96
97| 参数名      | 类型                            | 必填 | 说明                           |
98| ----------- | ------------------------------- | ---- | ------------------------------ |
99| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
100
101## onDrop
102
103onDrop(event: (event: DragEvent, extraParams?: string) => void)
104
105绑定此事件的组件可作为释放目标。当在本组件范围内停止拖放行为时,将触发回调。如果开发者未在onDrop中主动调用event.setResult()来设置拖拽接收的结果,对于系统支持的默认可拖入组件,处理结果将依据系统实际处理的数据。对于其他组件,系统将默认视为数据接收成功。
106
107**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
108
109**系统能力:** SystemCapability.ArkUI.ArkUI.Full
110
111**参数:**
112
113| 参数名      | 类型                            | 必填 | 说明                           |
114| ----------- | ------------------------------- | ---- | ------------------------------ |
115| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
116
117## onDrop<sup>15+</sup>
118
119onDrop(eventCallback: OnDragEventCallback, dropOptions?: DropOptions)
120
121绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。如果开发者没有在onDrop中主动调用event.setResult()设置拖拽接收的结果,若拖拽组件为系统支持默认拖入的组件,以系统实际处理数据结果为准,其它组件则系统按照数据接收成功处理。
122
123**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。
124
125**系统能力:** SystemCapability.ArkUI.ArkUI.Full
126
127**参数:**
128
129| 参数名      | 类型                            | 必填 | 说明                           |
130| ----------- | ------------------------------- | ---- | ------------------------------ |
131| eventCallback  | (event: DragEvent, extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
132| dropOptions  | bool   | 否   | 设置拖拽是否提前获取数据。<br/>**说明:**<br/> 当使用startDataLoading获取数据时需设置该参数为true,防止拖拽提前获取数据。 |
133
134## onDragEnd<sup>10+</sup>
135
136onDragEnd(event: (event: DragEvent, extraParams?: string) => void)
137
138绑定此事件的组件触发的拖拽结束后,触发回调。
139
140**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
141
142**系统能力:** SystemCapability.ArkUI.ArkUI.Full
143
144**参数:**
145
146| 参数名      | 类型                            | 必填 | 说明                           |
147| ----------- | ------------------------------- | ---- | ------------------------------ |
148| event    | (event: [DragEvent](#dragevent7), extraParams?: string) => void   | 是   | 回调函数。<br/>**说明:**<br/> event为拖拽事件信息,不包括拖拽点坐标。<br/> extraParams为拖拽事件额外信息,需要解析为Json格式,参考[extraParams](#extraparams说明)说明。|
149
150## onPreDrag<sup>12+</sup>
151
152onPreDrag(event: (preDragStatus: PreDragStatus) => void)
153
154绑定此事件的组件,当触发拖拽发起前的不同阶段时,触发回调。
155
156**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
157
158**系统能力:** SystemCapability.ArkUI.ArkUI.Full
159
160**参数:**
161
162| 参数名      | 类型                            | 必填 | 说明                           |
163| ----------- | ------------------------------- | ---- | ------------------------------ |
164| callback    | Callback<(preDragStatus: [PreDragStatus](#predragstatus12枚举说明)> ) => void     | 是   | 回调函数。|
165
166## DragItemInfo说明
167
168**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
169
170**系统能力:** SystemCapability.ArkUI.ArkUI.Full
171
172| 名称      | 类型                                     | 必填   | 描述                                |
173| --------- | ---------------------------------------- | ---- | --------------------------------- |
174| pixelMap  | [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) | 否    | 设置拖拽过程中显示的图片。 |
175| builder   | [CustomBuilder](ts-types.md#custombuilder8) | 否    | 拖拽过程中显示自定义组件,如果设置了pixelMap,则忽略此值。<br /> **说明:** <br/>不支持全局builder。如果builder中使用了[Image](ts-basic-components-image.md)组件,应尽量开启同步加载,即配置Image的[syncLoad](ts-basic-components-image.md#syncload8)为true。该builder只用于生成当次拖拽中显示的图片,builder的修改不会同步到当前正在拖拽的图片,对builder的修改需要在下一次拖拽时生效。|
176| extraInfo | string                                   | 否    | 拖拽项的描述。                           |
177
178## PreviewConfiguration<sup>15+</sup>
179
180配置自定义拖拽过程中的预览图样式。
181
182**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。
183
184**系统能力:** SystemCapability.ArkUI.ArkUI.Full
185
186| 名称       | 类型 | 只读 | 可选 | 说明                                                         |
187| ---------- | ---- | ---- | ---- | ------------------------------------------------------------ |
188| onlyForLifting | boolean | 否    | 是    | 自定义配置的预览图是否仅用于浮起。<br /> **说明:** <br/>默认值为false。设置为true时,如果发起长按拖拽,浮起时的跟手图为自定义配置的预览图,拖拽时的跟手图不使用[dragPreview](ts-universal-attributes-drag-drop.md#dragpreview11)属性,优先使用开发者在[onDragStart](ts-universal-events-drag-drop.md#ondragstart)中返回的背板图,如果[onDragStart](ts-universal-events-drag-drop.md#ondragstart)中没有返回背板图则使用组件自截图。|
189| delayCreating  | boolean | 否    | 是    | 组件预览builder是否在设置时加载。<br/>默认值为false。|
190
191## extraParams说明
192
193  用于返回组件在拖拽中需要用到的额外信息。
194
195  extraParams是Json对象转换的string字符串,可以通过Json.parse转换的Json对象获取如下属性。
196
197| 名称          | 类型   | 描述                                       |
198| ------------- | ------ | ---------------------------------------- |
199| selectedIndex | number | 当拖拽事件设在父容器的子元素时,selectedIndex表示当前被拖拽子元素是父容器第selectedIndex个子元素,selectedIndex从0开始。<br/>仅在ListItem组件的拖拽事件中生效。 |
200| insertIndex   | number | 当前拖拽元素在List组件中放下时,insertIndex表示被拖拽元素插入该组件的第insertIndex个位置,insertIndex从0开始。<br/>仅在List组件的拖拽事件中生效。 |
201
202## DragEvent<sup>7+</sup>
203
204**系统能力:** SystemCapability.ArkUI.ArkUI.Full
205
206### 属性
207
208**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
209
210**系统能力:** SystemCapability.ArkUI.ArkUI.Full
211
212| 名称     | 类型  | 描述             |
213| ------ | ------ | ---------------- |
214| useCustomDropAnimation<sup>10+</sup> | boolean | 当拖拽结束时,是否禁用系统默认落位动效。<br/>应用可将该值设定为true来禁用系统默认落位动效,并实现自己的自定义落位动效。<br/>当不配置或设置为false时,系统默认落位动效生效,当松手位置的控件可接收拖拽的数据时,落位为缩小消失动效,若不可接收数据,则为放大消失动效。<br/>当未禁用系统默认落位动效情况下,应用不应再实现自定义动效,以避免动效上的冲突。|
215|dragBehavior<sup>10+</sup> | [DragBehavior](#dragbehavior10) | 切换复制和剪贴模式的角标显示状态。 |
216
217### 方法
218
219**系统能力:** SystemCapability.ArkUI.ArkUI.Full
220
221| 名称     | 返回值类型                            | 描述                           |
222| ----------- | ------------------------------- | ------------------------------ |
223| setData(unifiedData: [UnifiedData](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#unifieddata))<sup>10+</sup>       | void   | 向DragEvent中设置拖拽相关数据。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
224| getData()<sup>10+</sup> | [UnifiedData](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#unifieddata) | 从DragEvent中获取拖拽相关数据。数据获取结果请参考错误码说明。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
225| getSummary()<sup>10+</sup> | [Summary](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#summary) | 从DragEvent中获取拖拽相关数据的简介。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
226| setResult(dragRect: [DragResult](#dragresult10枚举说明))<sup>10+</sup> | void | 向DragEvent中设置拖拽结果。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
227| getResult()<sup>10+</sup> | [DragResult](#dragresult10枚举说明) | 从DragEvent中获取拖拽结果。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
228| getPreviewRect()<sup>10+</sup> | [Rectangle](ts-universal-attributes-touch-target.md#rectangle对象说明) | 获取拖拽跟手图相对于当前窗口的位置,以及跟手图尺寸信息,单位VP,其中x和y代表跟手图左上角的窗口坐标,width和height代表跟手图的尺寸。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
229| getVelocityX()<sup>10+</sup> | number | 获取当前拖拽的x轴方向拖动速度。坐标轴原点为屏幕左上角,单位为vp,分正负方向速度,从左往右为正,反之为负。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
230| getVelocityY()<sup>10+</sup> | number | 获取当前拖拽的y轴方向拖动速度。坐标轴原点为屏幕左上角,单位为vp,分正负方向速度,从上往下为正,反之为负。 |
231| getVelocity()<sup>10+</sup> | number | 获取当前拖拽的主方向拖动速度。为xy轴方向速度的平方和的算术平方根。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
232| getWindowX()<sup>10+</sup> | number | 当前拖拽点相对于窗口左上角的x轴坐标,单位为vp。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
233| getWindowY()<sup>10+</sup> | number | 当前拖拽点相对于窗口左上角的y轴坐标,单位为vp。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
234| getDisplayX()<sup>10+</sup> | number | 当前拖拽点相对于屏幕左上角的x轴坐标,单位为vp。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
235| getDisplayY()<sup>10+</sup> | number | 当前拖拽点相对于屏幕左上角的y轴坐标,单位为vp。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
236| getModifierKeyState<sup>12+</sup> | (Array&lt;string&gt;) => bool | 获取功能键按压状态。报错信息请参考以下错误码。支持功能键 'Ctrl'\|'Alt'\|'Shift'\|'Fn',设备外接带Fn键的键盘不支持Fn键查询。 <br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。|
237| startDataLoading(options: [DataSyncOptions](#datasyncoptions15))<sup>15+</sup> | string | 异步获取拖拽数据,并通知开发者当前数据同步进度,仅支持在onDrop阶段使用。数据传输过程中可使用[cancelDataLoading](../js-apis-arkui-UIContext.md#canceldataloading15)接口取消。<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 |
238| getX()<sup>(deprecated)</sup> | number | 当前拖拽点相对于窗口左上角的x轴坐标,单位为vp。<br>从API Version 10开始不再维护,建议使用getWindowX()代替。 |
239| getY()<sup>(deprecated)</sup> | number | 当前拖拽点相对于窗口左上角的y轴坐标,单位为vp。<br>从API Version 10开始不再维护,建议使用getWindowY()代替。 |
240
241
242**错误码:**
243
244以下错误码的详细介绍请参见[通用错误码](../../errorcode-universal.md)和[drag-event(拖拽事件)](../errorcode-drag-event.md)错误码。
245
246| 错误码ID   | 错误信息 |
247| --------- | ------- |
248| 401       | Parameter error. Possible causes: 1. Incorrect parameter types. 2. Parameter verification failed. |
249| 190001    | Data not found.|
250| 190002    | Data error. |
251| 190003    | Operation on allowed for current pharse. |
252
253## DragResult<sup>10+</sup>枚举说明
254
255**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
256
257**系统能力:** SystemCapability.ArkUI.ArkUI.Full
258
259| 名称 | 描述 |
260| ----- | ----------------- |
261| DRAG_SUCCESSFUL | 拖拽成功,在onDrop中使用。 |
262| DRAG_FAILED | 拖拽失败,在onDrop中使用。 |
263| DRAG_CANCELED | 拖拽取消,在onDrop中使用。 |
264| DROP_ENABLED | 组件允许落入,在onDragMove中使用。 |
265| DROP_DISABLED | 组件不允许落入,在onDragMove中使用。 |
266
267## DragBehavior<sup>10+</sup>
268
269当设置[DragResult](#dragresult10枚举说明)为DROP_ENABLED后,可设置DragBehavior为复制(COPY)或剪切(MOVE)。DragBehavior用来向开发者描述数据的处理方式是复制(COPY)还是剪切(MOVE),但无法最终决定对数据的实际处理方式。DragBehavior会通过onDragEnd带回给数据拖出方,发起拖拽的一方可通过DragBehavior来区分做出的是复制还是剪切数据的不同行为。
270
271**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
272
273**系统能力:** SystemCapability.ArkUI.ArkUI.Full
274
275| 名称 | 描述 |
276| ----- | ----------------- |
277| COPY | 指定对数据的处理方式为复制。|
278| MOVE| 指定对数据的处理方式为剪切。|
279
280## PreDragStatus<sup>12+</sup>枚举说明
281
282**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
283
284**系统能力:** SystemCapability.ArkUI.ArkUI.Full
285
286| 名称 | 值 | 描述 |
287| ---- | - | ----------------- |
288| ACTION_DETECTING_STATUS | 0 | 拖拽手势启动阶段。(按下50ms时触发) |
289| READY_TO_TRIGGER_DRAG_ACTION | 1 | 拖拽准备完成,可发起拖拽阶段。(按下500ms时触发) |
290| PREVIEW_LIFT_STARTED | 2 | 拖拽浮起动效发起阶段。(按下800ms时触发) |
291| PREVIEW_LIFT_FINISHED | 3 | 拖拽浮起动效结束阶段。(浮起动效完全结束时触发) |
292| PREVIEW_LANDING_STARTED | 4 | 拖拽落回动效发起阶段。(落回动效发起时触发) |
293| PREVIEW_LANDING_FINISHED | 5 | 拖拽落回动效结束阶段。(落回动效结束时触发) |
294| ACTION_CANCELED_BEFORE_DRAG | 6 | 拖拽浮起落位动效中断。(已满足READY_TO_TRIGGER_DRAG_ACTION状态后,未达到动效阶段,手指抬手时触发) |
295| PREPARING_FOR_DRAG_DETECTION<sup>18+</sup>  | 7 | 拖拽准备完成,可发起拖拽阶段。(按下350ms时触发) |
296
297## executeDropAnimation<sup>18+</sup>
298
299设置一个自定义落位动效的执行函数,仅在useCustomDropAnimation为true时有效。
300
301**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
302
303**系统能力:** SystemCapability.ArkUI.ArkUI.Full
304
305| 参数名     | 类型  | 描述             |
306| ------ | ------ | ---------------- |
307| customDropAnimation | Callback\<void\>  |  在独立的接口中实现自定义落位动效。<br/> **说明:** <br/>1. 该接口仅在 onDrop 回调中使用有效。<br/> 2. 使用前需设置 useCustomDropAnimation 为 true,否则该接口不生效。<br/> 3. 不要在动画callback中实现与动效无关的逻辑,避免影响执行效率。|
308
309## DataSyncOptions<sup>15+</sup>
310
311type DataSyncOptions = GetDataParams
312
313作为startDataLoading的入参对象
314
315**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。
316
317**系统能力:** SystemCapability.ArkUI.ArkUI.Full
318
319| 类型 | 说明 |
320| ----- | ----------------- |
321| [GetDataParams](../../apis-arkdata/js-apis-data-unifiedDataChannel.md#getdataparams15) | 表示从UDMF获取数据时的参数,包含目标路径、文件冲突选项、进度条类型等。|
322
323## 示例
324
325### 示例1(设置组件拖拽和落入)
326
327该示例展示了部分组件(如Image和Text等)拖拽和可落入区域的设置。
328
329```ts
330// xxx.ets
331import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
332import { promptAction } from '@kit.ArkUI';
333import { BusinessError } from '@kit.BasicServicesKit';
334
335@Entry
336@Component
337struct Index {
338  @State targetImage: string = '';
339  @State targetText: string = 'Drag Text';
340  @State imageWidth: number = 100;
341  @State imageHeight: number = 100;
342  @State imgState: Visibility = Visibility.Visible;
343  @State abstractContent: string = "abstract";
344  @State textContent: string = "";
345  @State backGroundColor: Color = Color.Transparent;
346
347  @Builder
348  pixelMapBuilder() {
349    Column() {
350      Image($r('app.media.icon'))
351        .width(120)
352        .height(120)
353        .backgroundColor(Color.Yellow)
354    }
355  }
356
357  getDataFromUdmfRetry(event: DragEvent, callback: (data: DragEvent) => void) {
358    try {
359      let data: UnifiedData = event.getData();
360      if (!data) {
361        return false;
362      }
363      let records: Array<unifiedDataChannel.UnifiedRecord> = data.getRecords();
364      if (!records || records.length <= 0) {
365        return false;
366      }
367      callback(event);
368      return true;
369    } catch (e) {
370      console.log("getData failed, code = " + (e as BusinessError).code + ", message = " + (e as BusinessError).message);
371      return false;
372    }
373  }
374
375  getDataFromUdmf(event: DragEvent, callback: (data: DragEvent) => void) {
376    if (this.getDataFromUdmfRetry(event, callback)) {
377      return;
378    }
379    setTimeout(() => {
380      this.getDataFromUdmfRetry(event, callback);
381    }, 1500);
382  }
383
384  private PreDragChange(preDragStatus: PreDragStatus): void {
385    if (preDragStatus == PreDragStatus.READY_TO_TRIGGER_DRAG_ACTION) {
386      this.backGroundColor = Color.Red;
387    } else if (preDragStatus == PreDragStatus.ACTION_CANCELED_BEFORE_DRAG
388      || preDragStatus == PreDragStatus.PREVIEW_LANDING_FINISHED) {
389      this.backGroundColor = Color.Blue;
390    }
391  }
392
393  build() {
394    Row() {
395      Column() {
396        Text('start Drag')
397          .fontSize(18)
398          .width('100%')
399          .height(40)
400          .margin(10)
401          .backgroundColor('#008888')
402        Image($r('app.media.icon'))
403          .width(100)
404          .height(100)
405          .draggable(true)
406          .margin({ left: 15 })
407          .visibility(this.imgState)
408          .onDragEnd((event) => {
409            // onDragEnd里取到的result值在接收方onDrop设置
410            if (event.getResult() === DragResult.DRAG_SUCCESSFUL) {
411              this.getUIContext().getPromptAction().showToast({ duration: 100, message: 'Drag Success' });
412            } else if (event.getResult() === DragResult.DRAG_FAILED) {
413              this.getUIContext().getPromptAction().showToast({ duration: 100, message: 'Drag failed' });
414            }
415          })
416        Text('test drag event')
417          .width('100%')
418          .height(100)
419          .draggable(true)
420          .margin({ left: 15 })
421          .copyOption(CopyOptions.InApp)
422        TextArea({ placeholder: 'please input words' })
423          .copyOption(CopyOptions.InApp)
424          .width('100%')
425          .height(50)
426          .draggable(true)
427        Search({ placeholder: 'please input you word' })
428          .searchButton('Search')
429          .width('100%')
430          .height(80)
431          .textFont({ size: 20 })
432
433        Column() {
434          Text('this is abstract')
435            .fontSize(20)
436            .width('100%')
437        }.margin({ left: 40, top: 20 })
438        .width('100%')
439        .height(100)
440        .onDragStart((event) => {
441          this.backGroundColor = Color.Transparent;
442          let data: unifiedDataChannel.PlainText = new unifiedDataChannel.PlainText();
443          data.abstract = 'this is abstract';
444          data.textContent = 'this is content this is content';
445          (event as DragEvent).setData(new unifiedDataChannel.UnifiedData(data));
446        })
447        .onPreDrag((status: PreDragStatus) => {
448          this.PreDragChange(status);
449        })
450        .backgroundColor(this.backGroundColor)
451      }.width('45%')
452      .height('100%')
453
454      Column() {
455        Text('Drag Target Area')
456          .fontSize(20)
457          .width('100%')
458          .height(40)
459          .margin(10)
460          .backgroundColor('#008888')
461        Image(this.targetImage)
462          .width(this.imageWidth)
463          .height(this.imageHeight)
464          .draggable(true)
465          .margin({ left: 15 })
466          .border({ color: Color.Black, width: 1 })
467          .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
468          .onDrop((dragEvent?: DragEvent) => {
469            this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => {
470              let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords();
471              let rect: Rectangle = event.getPreviewRect();
472              this.imageWidth = Number(rect.width);
473              this.imageHeight = Number(rect.height);
474              this.targetImage = (records[0] as unifiedDataChannel.Image).imageUri;
475              event.useCustomDropAnimation = false;
476              this.imgState = Visibility.None;
477              // 显式设置result为successful,则将该值传递给拖出方的onDragEnd
478              event.setResult(DragResult.DRAG_SUCCESSFUL);
479            })
480          })
481
482        Text(this.targetText)
483          .width('100%')
484          .height(100)
485          .border({ color: Color.Black, width: 1 })
486          .margin(15)
487          .allowDrop([uniformTypeDescriptor.UniformDataType.PLAIN_TEXT])
488          .onDrop((dragEvent?: DragEvent) => {
489            this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => {
490              let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords();
491              let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText;
492              this.targetText = plainText.textContent;
493            })
494          })
495
496        Column() {
497          Text(this.abstractContent).fontSize(20).width('100%')
498          Text(this.textContent).fontSize(15).width('100%')
499        }
500        .width('100%')
501        .height(100)
502        .margin(20)
503        .border({ color: Color.Black, width: 1 })
504        .allowDrop([uniformTypeDescriptor.UniformDataType.PLAIN_TEXT])
505        .onDrop((dragEvent?: DragEvent) => {
506          this.getDataFromUdmf((dragEvent as DragEvent), (event: DragEvent) => {
507            let records: Array<unifiedDataChannel.UnifiedRecord> = event.getData().getRecords();
508            let plainText: unifiedDataChannel.PlainText = records[0] as unifiedDataChannel.PlainText;
509            this.abstractContent = plainText.abstract as string;
510            this.textContent = plainText.textContent;
511          })
512        })
513      }.width('45%')
514      .height('100%')
515      .margin({ left: '5%' })
516    }
517    .height('100%')
518  }
519}
520```
521![events-drag-drop](figures/events-drag-drop.png)
522
523### 示例2(自定义落位动效)
524
525通过自定义接口executeDropAnimation,实现落位动效。
526```ts
527import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
528
529@Entry
530@Component
531struct DropAnimationExample {
532  @State targetImage: string = '';
533  @State targetText: string = 'Drag Text';
534  @State hyperLinkText: string = 'HyperLink';
535  @State hyperLinkContent: string = 'HyperLink';
536  @State imageWidth: number = 100;
537  @State imageHeight: number = 100;
538  @State imgState: Visibility = Visibility.Visible;
539  @State videoSrc: string = 'resource://RAWFILE/02.mp4';
540  @State abstractContent: string = "abstract";
541  @State textContent: string = "";
542
543  customDropAnimation =
544    () => {
545      this.getUIContext().animateTo({ duration: 1000, curve: Curve.EaseOut, playMode: PlayMode.Normal }, () => {
546        this.imageWidth = 200;
547        this.imageHeight = 200;
548        this.imgState = Visibility.None;
549      })
550    }
551
552  build() {
553    Row() {
554      Column() {
555        Image($r('app.media.app_icon'))
556          .width(100)
557          .height(100)
558          .draggable(true)
559          .margin({ left: 15 ,top: 40})
560          .visibility(this.imgState)
561          .onDragStart((event) => {
562          })
563          .onDragEnd((event) => {
564            if (event.getResult() === DragResult.DRAG_SUCCESSFUL) {
565              console.info('Drag Success');
566            } else if (event.getResult() === DragResult.DRAG_FAILED) {
567              console.error('Drag failed');
568            }
569          })
570      }.width('45%')
571      .height('100%')
572      Column() {
573        Text('Drag Target Area')
574          .fontSize(20)
575          .width(180)
576          .height(40)
577          .textAlign(TextAlign.Center)
578          .margin(10)
579          .backgroundColor('rgb(240,250,255)')
580        Column() {
581          Image(this.targetImage)
582            .width(this.imageWidth)
583            .height(this.imageHeight)
584        }
585        .draggable(true)
586        .margin({ left: 15 })
587        .border({ color: Color.Black, width: 1 })
588        .allowDrop([uniformTypeDescriptor.UniformDataType.IMAGE])
589        .onDrop((dragEvent: DragEvent) => {
590          let records: Array<unifiedDataChannel.UnifiedRecord> = dragEvent.getData().getRecords();
591          let rect: Rectangle = dragEvent.getPreviewRect();
592          this.imageWidth = Number(rect.width);
593          this.imageHeight = Number(rect.height);
594          this.targetImage = (records[0] as unifiedDataChannel.Image).imageUri;
595          dragEvent.useCustomDropAnimation = true;
596          dragEvent.executeDropAnimation(this.customDropAnimation)
597        })
598        .width(this.imageWidth)
599        .height(this.imageHeight)
600      }.width('45%')
601      .height('100%')
602      .margin({ left: '5%' })
603    }
604    .height('100%')
605  }
606}
607```
608![executeDropAnimation](figures/executeDropAnimation.gif)
609
610### 示例3(拖拽异步获取数据)
611
612通过startDataLoading实现拖拽异步获取数据。
613
614```ts
615import { unifiedDataChannel, uniformTypeDescriptor } from '@kit.ArkData';
616import { fileUri, fileIo as fs } from '@kit.CoreFileKit'
617import { common } from '@kit.AbilityKit'
618
619@Entry
620@Component
621struct ImageExample {
622  @State uri: string = "";
623  @State blockArr: string[] = [];
624  uiContext = this.getUIContext();
625  udKey: string = '';
626
627  build() {
628    Column() {
629      Text('Image拖拽')
630        .fontSize('30dp')
631      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
632        Image($r('app.media.startIcon'))
633          .width(100)
634          .height(100)
635          .border({ width: 1 })
636          .draggable(true)
637          .onDragStart((event:DragEvent) => {
638            const context: Context|undefined = this.uiContext.getHostContext();
639            if(context) {
640              let data = context.resourceManager.getMediaContentSync($r('app.media.startIcon').id, 120);
641              const arrayBuffer: ArrayBuffer = data.buffer.slice(data.byteOffset, data.byteLength + data.byteOffset);
642              let filePath = context.filesDir + '/test.png';
643              let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
644              fs.writeSync(file.fd, arrayBuffer);
645              //获取图片的uri
646              let uri = fileUri.getUriFromPath(filePath);
647              let image: unifiedDataChannel.Image = new unifiedDataChannel.Image();
648              image.imageUri = uri;
649              let dragData: unifiedDataChannel.UnifiedData = new unifiedDataChannel.UnifiedData(image);
650              (event as DragEvent).setData(dragData);
651            }
652          })
653      }
654      .margin({ bottom: 20 })
655      Row() {
656        Column(){
657          Text('可释放区域')
658            .fontSize('15dp')
659            .height('10%')
660          List(){
661            ForEach(this.blockArr, (item:string, index) => {
662              ListItem() {
663                Image(item)
664                  .width(100)
665                  .height(100)
666                  .border({width: 1})
667              }
668              .margin({ left: 30 , top : 30})
669            }, (item:string) => item)
670          }
671          .border({width: 1})
672          .height('90%')
673          .width('100%')
674          .onDrop((event?: DragEvent, extraParams?: string) => {
675            console.log("enter onDrop")
676            let context = this.uiContext.getHostContext() as common.UIAbilityContext;
677            let pathDir: string = context.distributedFilesDir;
678            let destUri = fileUri.getUriFromPath(pathDir);
679            let progressListener: unifiedDataChannel.DataProgressListener = (progress: unifiedDataChannel.ProgressInfo, dragData: UnifiedData|null) => {
680              if(dragData != null) {
681                let arr:Array<unifiedDataChannel.UnifiedRecord> = dragData.getRecords();
682                if(arr.length > 0) {
683                  if (arr[0].getType() === uniformTypeDescriptor.UniformDataType.IMAGE) {
684                    let image = arr[0] as unifiedDataChannel.Image;
685                    this.uri = image.imageUri;
686                    this.blockArr.splice(JSON.parse(extraParams as string).insertIndex, 0, this.uri);
687                  }
688                } else {
689                  console.log('dragData arr is null');
690                }
691              } else {
692                console.log('dragData is undefined');
693              }
694              console.log(`percentage: ${progress.progress}`);
695            };
696            let options: DataSyncOptions = {
697              destUri: destUri,
698              fileConflictOptions: unifiedDataChannel.FileConflictOptions.OVERWRITE,
699              progressIndicator: unifiedDataChannel.ProgressIndicator.DEFAULT,
700              dataProgressListener: progressListener,
701            }
702            try {
703              this.udKey = (event as DragEvent).startDataLoading(options);
704              console.log('udKey: ', this.udKey);
705            } catch(e) {
706              console.log(`startDataLoading errorCode: ${e.code}, errorMessage: ${e.message}`);
707            }
708          }, {disableDataPrefetch: true})
709        }
710        .height("50%")
711        .width("90%")
712        .border({ width: 1 })
713      }
714      Button('取消数据传输')
715        .onClick(() => {
716          try {
717            this.getUIContext().getDragController().cancelDataLoading(this.udKey);
718          } catch (e) {
719            console.log(`cancelDataLoading errorCode: ${e.code}, errorMessage: ${e.message}`);
720          }
721        })
722        .margin({top: 10})
723    }.width('100%')
724  }
725}
726```