• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 拖拽事件
2
3拖拽事件指组件被长按后拖拽时触发的事件。
4
5>  **说明:**
6>
7>  从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8
9## 事件
10
11| 名称                                                         | 支持冒泡 | 功能描述                                                     |
12| ------------------------------------------------------------ | -------- | ------------------------------------------------------------ |
13| onDragStart(event:&nbsp;(event:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;&nbsp;[CustomBuilder](ts-types.md#custombuilder8)) \| [DragItemInfo](#dragiteminfo说明) | 否       | 第一次拖拽此事件绑定的组件时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>返回值:当前跟手效果所拖拽的对象,用于显示拖拽时的提示组件。<br/>长按150ms可触发拖拽事件。优先级:长按手势配置时间小于等于150ms时,长按手势优先触发,否则拖拽事件优先触发。 |
14| onDragEnter(event:&nbsp;(event:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽进入组件范围内时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
15| onDragMove(event:&nbsp;(event:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽在组件范围内移动时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
16| onDragLeave(event:&nbsp;(event:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 拖拽离开组件范围内时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。<br/>当监听了onDrop事件时,此事件才有效。 |
17| onDrop(event:&nbsp;(event:&nbsp;[DragEvent](#dragevent说明),&nbsp;extraParams?:&nbsp;string)&nbsp;=&gt;&nbsp;void) | 否       | 绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。<br/>- event:拖拽事件信息,包括拖拽点坐标。<br/>- extraParams:拖拽事件额外信息,详见[extraParams](#extraparams说明)说明。 |
18
19## DragItemInfo说明
20| 属性名称          | 属性类型   | 必填 | 描述                                       |
21| ------------- | ------ | ------- |--------------------------------- |
22| pixelMap | [PixelMap](../apis/js-apis-image.md#pixelmap7) |  否  | 设置拖拽过程中显示的图片。 |
23| builder | [CustomBuilder](ts-types.md#custombuilder8) |  否  | 拖拽过程中显示自定义组件,如果设置了pixelMap,则忽略此值。 |
24| extraInfo | string |  否  | 拖拽项的描述。 |
25
26## extraParams说明<br>
27用于返回组件在拖拽中需要用到的额外信息。
28extraParams是Json对象转换的string字符串,可以通过Json.parse转换的Json对象获取如下属性。
29
30| 名称          | 类型   | 描述                                                         |
31| ------------- | ------ | ------------------------------------------------------------ |
32| selectedIndex | number | 当拖拽事件设在父容器的子元素时,selectedIndex表示当前被拖拽子元素是父容器第selectedIndex个子元素,selectedIndex从0开始。<br/>仅在ListItem组件的拖拽事件中生效。 |
33| insertIndex   | number | 当前拖拽元素在List组件中放下时,insertIndex表示被拖拽元素插入该组件的第insertIndex个位置,insertIndex从0开始。<br/>仅在List组件的拖拽事件中生效。 |
34
35## DragEvent说明
36| 名称   | 类型   | 功能描述                      |
37| ------ | ------ | ----------------------------- |
38| getX() | number | 当前拖拽点相对于屏幕左上角的x轴坐标,单位为vp。 |
39| getY() | number | 当前拖拽点相对于屏幕左上角的y轴坐标,单位为vp。 |
40
41## 示例
42
43```ts
44// xxx.ets
45@Extend(Text) function textStyle () {
46  .width('25%')
47  .height(35)
48  .fontSize(16)
49  .textAlign(TextAlign.Center)
50  .backgroundColor(0xAFEEEE)
51}
52
53@Entry
54@Component
55struct DragExample {
56  @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six']
57  @State text: string = ''
58  @State bool: boolean = true
59  @State eventType: string = ''
60  @State appleVisible: Visibility = Visibility.Visible
61  @State orangeVisible: Visibility = Visibility.Visible
62  @State bananaVisible: Visibility = Visibility.Visible
63  private dragList: string[] = ['apple', 'orange', 'banana']
64  @State fruitVisible: Visibility[] = [Visibility.Visible, Visibility.Visible, Visibility.Visible]
65  @State index: number = 0
66
67  // 自定义拖拽过程中显示的内容
68  @Builder pixelMapBuilder() {
69    Column() {
70      Text(this.text)
71        .width('50%')
72        .height(60)
73        .fontSize(16)
74        .borderRadius(10)
75        .textAlign(TextAlign.Center)
76        .backgroundColor(Color.Yellow)
77    }
78  }
79
80  build() {
81    Column() {
82      Text('There are three Text elements here')
83        .fontSize(12)
84        .fontColor(0xCCCCCC)
85        .width('90%')
86        .textAlign(TextAlign.Start)
87        .margin(5)
88      Row({ space: 15 }) {
89        ForEach(this.dragList, (item, index) => {
90          Text(item)
91            .textStyle()
92            .visibility(this.fruitVisible[index])
93            .onDragStart(() => {
94              this.bool = true
95              this.text = item
96              this.fruitVisible[index] = Visibility.None
97              return this.pixelMapBuilder
98            })
99            .onTouch((event: TouchEvent) => {
100              if (event.type === TouchType.Down) {
101                this.eventType = 'Down'
102                this.index = index
103              }
104              if (event.type === TouchType.Up) {
105                this.eventType = 'Up'
106                if (this.bool) {
107                  this.fruitVisible[index] = Visibility.Visible
108                }
109              }
110            })
111        })
112      }.padding({ top: 10, bottom: 10 }).margin(10)
113
114      Text('This is a List element')
115        .fontSize(12)
116        .fontColor(0xCCCCCC)
117        .width('90%')
118        .textAlign(TextAlign.Start)
119        .margin(15)
120      List({ space: 20 }) {
121        ForEach(this.numbers, (item) => {
122          ListItem() {
123            Text(item)
124              .width('100%')
125              .height(80)
126              .fontSize(16)
127              .borderRadius(10)
128              .textAlign(TextAlign.Center)
129              .backgroundColor(0xAFEEEE)
130          }
131        }, item => item)
132      }
133      .editMode(true)
134      .height('50%')
135      .width('90%')
136      .border({ width: 1 })
137      .padding(15)
138      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 })
139      .onDragEnter((event: DragEvent, extraParams: string) => {
140        console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
141      })
142      .onDragMove((event: DragEvent, extraParams: string) => {
143        console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
144      })
145      .onDragLeave((event: DragEvent, extraParams: string) => {
146        console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
147      })
148      .onDrop((event: DragEvent, extraParams: string) => {
149        let jsonString = JSON.parse(extraParams);
150        if (this.bool) {
151          // 通过splice方法插入元素
152          this.numbers.splice(jsonString.insertIndex, 0, this.text)
153          this.bool = false
154        }
155        this.fruitVisible[this.index] = Visibility.None
156      })
157    }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 })
158  }
159}
160```
161
162![zh-cn_image_0000001252667389](figures/zh-cn_image_0000001252667389.gif)
163