自定义拖拽事件

开发者可以通过实现通用拖拽事件来自定义拖拽响应:

  1. 设置需要拖拽组件的draggable属性为true,并在onDragStart回调中设置需要传递的数据。
  2. 设置接受拖拽组件的allowDrop允许落入的数据类型,在onDrop回调中接收拖拽的数据。

属性

名称 参数类型 描述
allowDrop Array 设置该组件上允许落入的数据类型。 默认值:空
draggable boolean 设置该组件是否允许进行拖拽。 默认值:false

事件

名称 支持冒泡 功能描述
onDragStart(event: (event?: DragEvent, extraParams?: string) => CustomBuilder | DragItemInfo) 第一次拖拽此事件绑定的组件时,长按时间 >= 500ms,然后手指移动距离 >= 10vp,触发回调。 - event:拖拽事件信息,详见DragEvent。 - extraParams:拖拽事件额外信息,详见extraParams说明。 返回值:拖拽过程中显示的组件信息。 触发条件:长按时间 >= 500ms。 事件优先级:长按触发时间 < 500ms,长按事件优先拖拽事件响应,长按触发时间 >= 500ms,拖拽事件优先长按事件响应。
onDragEnter(event: (event?: DragEvent, extraParams?: string) => void) 拖拽进入组件范围内时,触发回调。 - event:拖拽事件信息,包括拖拽点坐标。 - extraParams:拖拽事件额外信息,详见extraParams说明。 当监听了onDrop事件时,此事件才有效。
onDragMove(event: (event?: DragEvent, extraParams?: string) => void) 拖拽在组件范围内移动时,触发回调。 - event:拖拽事件信息,包括拖拽点坐标。 - extraParams:拖拽事件额外信息,详见extraParams说明。 当监听了onDrop事件时,此事件才有效。
onDragLeave(event: (event?: DragEvent, extraParams?: string) => void) 拖拽离开组件范围内时,触发回调。 - event:拖拽事件信息,包括拖拽点坐标。 - extraParams:拖拽事件额外信息,详见extraParams说明。 当监听了onDrop事件时,此事件才有效。
onDrop(event: (event?: DragEvent, extraParams?: string) => void) 绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。 - event:拖拽事件信息,包括拖拽点坐标。 - extraParams:拖拽事件额外信息,详见extraParams说明。
onDragEnd(event: (event?: DragEvent, extraParams?: string) => void)10+ 绑定此事件的组件触发的拖拽结束后,触发回调。 - event:拖拽事件信息,包括拖拽点坐标。 - extraParams:拖拽事件额外信息,详见extraParams说明

样例

import UTD from '@ohos.data.uniformTypeDescriptor';
import UDC from '@ohos.data.unifiedDataChannel';

const TAG = 'DragTest'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State texts: Array<String> = []

  build() {
    Row() {
      Column({ space: 20 }) {
        Text(this.message)
          .fontSize(50)
          .draggable(true)
          .onDragStart((event: DragEvent) => {
            console.info(TAG, `拖拽开始 X=${event.getWindowX()} Y=${event.getWindowY()}`)
            // 设置拖拽传递的数据
            let text = new UDC.PlainText()
            text.textContent = this.message
            event.setData(new UDC.UnifiedData(text))
          })
          .onDragEnd((event: DragEvent) => {
            console.info(TAG, `拖拽结束 X=${event.getWindowX()} Y=${event.getWindowY()}`)
          })

        List() {
          ForEach(this.texts, (text: string) => {
            ListItem() {
              Text(text).fontSize(20)
            }
          })
        }
        .width('90%')
        .height('80%')
        .border({ color: Color.Black, width: 1 })
        // 设置支持拖入的数据类型
        .allowDrop([UTD.UniformDataType.PLAIN_TEXT])
        .onDragEnter((event: DragEvent) => {
          console.info(TAG, `拖拽动作进入 X=${event.getWindowX()} Y=${event.getWindowY()}`)
        })
        .onDragMove((event: DragEvent) => {
          console.info(TAG, `拖拽动作移动 X=${event.getWindowX()} Y=${event.getWindowY()}`)
        })
        .onDragLeave((event: DragEvent) => {
          console.info(TAG, `拖拽动作离开 X=${event.getWindowX()} Y=${event.getWindowY()}`)
        })
        .onDrop((event: DragEvent) => {
          try {
            console.info(TAG, `拖拽动作完成 X=${event.getWindowX()} Y=${event.getWindowY()}`)
            let records = event.getData().getRecords()
            let plainText: UDC.PlainText = records[0] as UDC.PlainText
            this.texts.push(plainText.textContent)
          } catch (err) {
            console.info(TAG, `出错了 ${JSON.stringify(err)}`)
          }
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

img

img

需要注意的是,在.onDragEnd回调中,试图获取拖拽结束时候的坐标,获取到的是(0, 0),需要在.onDrop回调中,才能拿到正确的坐标。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐