• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 拖拽事件
2
3拖拽事件指组件被长按后拖拽时触发的事件。
4
5>  **说明:**
6>
7>  从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8>
9> 应用本身预置的资源文件(即应用在安装前的HAP包中已经存在的资源文件)仅支持本地应用内拖拽。
10
11ArkUI框架对以下组件实现了默认的拖拽能力,支持对数据的拖出或拖入响应,开发者只需要将这些组件的[draggale](ts-universal-attributes-drag-drop.md)属性设置为true,即可使用默认拖拽能力。
12
13- 默认支持拖出能力的组件(可从组件上拖出数据):Search、TextInput、TextArea、RichEditor、Text、Image、FormComponent、Hyperlink
14
15- 默认支持拖入能力的组件(目标组件可响应拖入数据):Search、TextInput、TextArea、Video
16
17开发者也可以通过实现通用拖拽事件来自定义拖拽响应。
18
19其他组件需要开发者将draggable属性设置为true,并在onDragStart等接口中实现数据传输相关内容,才能正确处理拖拽。
20
21## 事件
22
23| 名称                                                         | 支持冒泡 | 功能描述                                                     |
24| ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |
25| onDragStart(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;&nbsp;[CustomBuilder](ts-types.md#custombuilder8) \| [DragItemInfo](#dragiteminfo说明)) | 否       | 第一次拖拽此事件绑定的组件时,触发回调。<br/>- event:拖拽事件信息,详见[DragEvent](#dragevent说明)。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/> 返回值:拖拽过程中显示的组件信息。<br/>触发条件:长按时间 >= 500ms。<br> 事件优先级:长按触发时间 < 500ms,长按事件 > 拖拽事件<br> 其他: 拖拽事件 > 长按事件。 |
26| onDragEnter(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽进入组件范围内时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
27| onDragMove(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽在组件范围内移动时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
28| onDragLeave(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽离开组件范围内时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
29| onDrop(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。 |
30| onDragEnd(event:&nbsp;(event?:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void)<sup>10+</sup> | 否       | 绑定此事件的组件触发的拖拽结束后,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。 |
31
32## DragItemInfo说明
33
34| 名称      | 类型                                     | 必填   | 描述                                |
35| --------- | ---------------------------------------- | ---- | --------------------------------- |
36| pixelMap  | [PixelMap](../apis/js-apis-image.md#pixelmap7) | 否    | 设置拖拽过程中显示的图片。                     |
37| builder   | [CustomBuilder](ts-types.md#custombuilder8) | 否    | 拖拽过程中显示自定义组件,如果设置了pixelMap,则忽略此值。 |
38| extraInfo | string                                   | 否    | 拖拽项的描述。                           |
39
40
41## extraParams说明
42
43  用于返回组件在拖拽中需要用到的额外信息。
44
45  extraParams是Json对象转换的string字符串,可以通过Json.parse转换的Json对象获取如下属性。
46
47| 名称          | 类型   | 描述                                       |
48| ------------- | ------ | ---------------------------------------- |
49| selectedIndex | number | 当拖拽事件设在父容器的子元素时,selectedIndex表示当前被拖拽子元素是父容器第selectedIndex个子元素,selectedIndex从0开始。<br/>仅在ListItem组件的拖拽事件中生效。 |
50| insertIndex   | number | 当前拖拽元素在List组件中放下时,insertIndex表示被拖拽元素插入该组件的第insertIndex个位置,insertIndex从0开始。<br/>仅在List组件的拖拽事件中生效。 |
51
52## DragEvent说明
53
54| 名称     | 类型  | 描述             |
55| ------ | ------ | ---------------- |
56| useCustomDropAnimation<sup>10+</sup> | boolean | 当拖拽结束时,是否使用系统默认落入动画。 |
57| setData(unifiedData: [UnifiedData](../apis/js-apis-data-unifiedDataChannel.md#unifieddata))<sup>10+</sup> | void | 向DragEvent中设置拖拽相关数据。 |
58| getData()<sup>10+</sup> | [UnifiedData](../apis/js-apis-data-unifiedDataChannel.md#unifieddata) | 从DragEvent中获取拖拽相关数据。数据获取结果请参考错误码说明。 |
59| getSummary()<sup>10+</sup> | [Summary](../apis/js-apis-data-unifiedDataChannel.md#summary) | 从DragEvent中获取拖拽相关数据的简介。 |
60| setResult(dragRect: [DragResult](#dragresult10枚举说明))<sup>10+</sup> | void | 向DragEvent中设置拖拽结果。 |
61| getResult()<sup>10+</sup> | [DragResult](#dragresult10枚举说明) | 从DragEvent中获取拖拽结果。 |
62| getPreviewRect()<sup>10+</sup> | [Rectangle](ts-universal-attributes-touch-target.md#rectangle对象说明) | 获取预览图所在的Rectangle。 |
63| getVelocityX()<sup>10+</sup> | number | 获取当前拖拽的x轴方向拖动速度。坐标轴原点为屏幕左上角,单位为vp,分正负方向速度,从左往右为正,反之为负。 |
64| getVelocityY()<sup>10+</sup> | number | 获取当前拖拽的y轴方向拖动速度。坐标轴原点为屏幕左上角,单位为vp,分正负方向速度,从上往下为正,反之为负。 |
65| getVelocity()<sup>10+</sup> | number | 获取当前拖拽的主方向拖动速度。为xy轴方向速度的平方和的算术平方根。 |
66| getWindowX()<sup>10+</sup> | number | 当前拖拽点相对于窗口左上角的x轴坐标,单位为vp。 |
67| getWindowY()<sup>10+</sup> | number | 当前拖拽点相对于窗口左上角的y轴坐标,单位为vp。 |
68| getDisplayX()<sup>10+</sup> | number | 当前拖拽点相对于屏幕左上角的x轴坐标,单位为vp。 |
69| getDisplayY()<sup>10+</sup> | number | 当前拖拽点相对于屏幕左上角的y轴坐标,单位为vp。 |
70| getX()<sup>(deprecated)</sup> | number | 当前拖拽点相对于窗口左上角的x轴坐标,单位为vp。<br>从API verdion 10开始不再维护,建议使用getWindowX()代替。 |
71| getY()<sup>(deprecated)</sup> | number | 当前拖拽点相对于窗口左上角的y轴坐标,单位为vp。<br>从API verdion 10开始不再维护,建议使用getWindowY()代替。 |
72
73**错误码:**
74
75以下错误码的详细介绍请参见[drag-event(拖拽事件)](../errorcodes/errorcode-drag-event.md)错误码。
76
77| 错误码ID   | 错误信息 |
78| --------- | ------- |
79| 190001    | GetData failed, data not found. |
80| 190002    | GetData failed, data error. |
81
82## DragResult<sup>10+</sup>枚举说明
83
84| 名称 | 描述 |
85| ----- | ----------------- |
86| DRAG_SUCCESSFUL | 拖拽成功 |
87| DRAG_FAILED | 拖拽失败 |
88| DRAG_CANCELED | 拖拽取消 |
89| DROP_ENABLED | 组件允许落入 |
90| DROP_DISABLED | 组件不允许落入 |
91
92## 示例
93
94```ts
95import UDC from '@ohos.data.unifiedDataChannel';
96import UTD from '@ohos.data.uniformTypeDescriptor';
97import promptAction from '@ohos.promptAction';
98import { BusinessError } from '@ohos.base';
99
100@Entry
101@Component
102struct Index {
103  @State targetImage: string = '';
104  @State targetText: string = 'Drag Text';
105  @State imageWidth: number = 100;
106  @State imageHeight: number = 100;
107  @State imgState: Visibility = Visibility.Visible;
108  @State videoSrc: string = 'resource://RAWFILE/02.mp4';
109  @State abstractContent: string = "abstract";
110  @State textContent: string = "";
111
112  getDataFromUdmfRetry(event: DragEvent, callback: (data: DragEvent)=>void)
113  {
114    try {
115      let data:UnifiedData = event.getData();
116      if (!data) {
117        return false;
118      }
119      let records: Array<UDC.UnifiedRecord> = data.getRecords();
120      if (!records || records.length <= 0) {
121        return false;
122      }
123      callback(event);
124      return true;
125    } catch (e) {
126      console.log("getData failed, code = " + (e as BusinessError).code + ", message = " + (e as BusinessError).message);
127      return false;
128    }
129  }
130
131  getDataFromUdmf(event: DragEvent, callback: (data: DragEvent)=>void)
132  {
133    if(this.getDataFromUdmfRetry(event, callback)) {
134      return;
135    }
136    setTimeout(()=>{
137      this.getDataFromUdmfRetry(event, callback);
138    }, 1500);
139  }
140
141  build() {
142    Row() {
143      Column() {
144        Text('start Drag')
145          .fontSize(18)
146          .width('100%')
147          .height(40)
148          .margin(10)
149          .backgroundColor('#008888')
150        Image($r('app.media.icon'))
151          .width(100)
152          .height(100)
153          .draggable(true)
154          .margin({left: 15})
155          .visibility(this.imgState)
156          .onDragEnd((event)=>{
157            if (event.getResult() === DragResult.DRAG_SUCCESSFUL) {
158              promptAction.showToast({duration: 100, message: 'Drag Success'});
159            } else if (event.getResult() === DragResult.DRAG_FAILED) {
160              promptAction.showToast({duration: 100, message: 'Drag failed'});
161            }
162          })
163        Text('test drag event')
164          .width('100%')
165          .height(100)
166          .draggable(true)
167          .margin({left: 15})
168          .copyOption(CopyOptions.InApp)
169        TextArea({placeholder: 'please input words'})
170          .copyOption(CopyOptions.InApp)
171          .width('100%')
172          .height(50)
173          .draggable(true)
174        Search({placeholder: 'please input you word'})
175          .searchButton('Search')
176          .width('100%')
177          .height(80)
178          .textFont({size: 20})
179        Column() {
180          Text('change video source')
181        }.draggable(true)
182        .onDragStart((event)=>{
183          let video: UDC.Video = new UDC.Video();
184          video.videoUri = '/resources/rawfile/01.mp4';
185          let data: UDC.UnifiedData = new UDC.UnifiedData(video);
186          (event as DragEvent).setData(data);
187        })
188        Column() {
189          Text('this is abstract')
190            .fontSize(20)
191            .width('100%')
192        }.margin({left: 40, top: 20})
193        .width('100%')
194        .height(100)
195        .onDragStart((event)=>{
196          let data: UDC.PlainText = new UDC.PlainText();
197          data.abstract = 'this is abstract';
198          data.textContent = 'this is content this is content';
199          (event as DragEvent).setData(new UDC.UnifiedData(data));
200        })
201      }.width('45%')
202      .height('100%')
203      Column() {
204        Text('Drag Target Area')
205          .fontSize(20)
206          .width('100%')
207          .height(40)
208          .margin(10)
209          .backgroundColor('#008888')
210        Image(this.targetImage)
211          .width(this.imageWidth)
212          .height(this.imageHeight)
213          .draggable(true)
214          .margin({left: 15})
215          .border({color: Color.Black, width: 1})
216          .allowDrop([UTD.UniformDataType.IMAGE])
217          .onDrop((dragEvent?: DragEvent)=> {
218            this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => {
219              let records: Array<UDC.UnifiedRecord> = event.getData().getRecords();
220              let rect: Rectangle = event.getPreviewRect();
221              this.imageWidth = Number(rect.width);
222              this.imageHeight = Number(rect.height);
223              this.targetImage = (records[0] as UDC.Image).imageUri;
224              event.useCustomDropAnimation = false;
225              animateTo({duration: 1000}, ()=>{
226                this.imageWidth = 100;
227                this.imageHeight = 100;
228                this.imgState = Visibility.None;
229              })
230              event.setResult(DragResult.DRAG_SUCCESSFUL);
231            })
232          })
233
234        Text(this.targetText)
235          .width('100%')
236          .height(100)
237          .border({color: Color.Black, width: 1})
238          .margin(15)
239          .allowDrop([UTD.UniformDataType.TEXT])
240          .onDrop((dragEvent?: DragEvent)=>{
241            this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => {
242              let records:Array<UDC.UnifiedRecord> = event.getData().getRecords();
243              let plainText:UDC.PlainText = records[0] as UDC.PlainText;
244              this.targetText = plainText.textContent;
245            })
246          })
247
248        Video({src: this.videoSrc, previewUri: $r('app.media.icon')})
249          .width('100%')
250          .height(200)
251          .controls(true)
252          .allowDrop([UTD.UniformDataType.VIDEO])
253
254        Column() {
255          Text(this.abstractContent).fontSize(20).width('100%')
256          Text(this.textContent).fontSize(15).width('100%')
257        }.width('100%').height(100).margin(20).border({color: Color.Black, width: 1})
258        .allowDrop([UTD.UniformDataType.PLAIN_TEXT])
259        .onDrop((dragEvent?: DragEvent)=>{
260          this.getDataFromUdmf((dragEvent as DragEvent), (event:DragEvent) => {
261            let records: Array<UDC.UnifiedRecord> = event.getData().getRecords();
262            let plainText: UDC.PlainText = records[0] as UDC.PlainText;
263            this.abstractContent = plainText.abstract as string;
264            this.textContent = plainText.textContent;
265          })
266        })
267      }.width('45%')
268      .height('100%')
269      .margin({left: '5%'})
270    }
271    .height('100%')
272  }
273}
274```
275