拖放

Jetpack Compose 通过两个修饰符支持拖放

例如,要在您的应用中启用用户拖动图像,请创建一个图像可组合项并添加 dragAndDropSource 修饰符。要设置拖放目标,请创建另一个图像可组合项并添加 dragAndDropTarget 修饰符。

这些修饰符可以应用于多个拖动源和多个拖放目标。

这些修饰符使应用能够使用 ClipData 在两个或多个可组合项之间共享数据,该数据与 View 实现兼容。

指定拖动源

要在组件内部启用拖动事件,请添加 dragAndDropSource 修饰符。这会将函数作为参数。在此函数内部,使用 DragAndDropTransferData 来表示可传输数据。数据可以是远程 URI、剪贴板上的富文本数据、本地文件等,但它们都需要封装在 ClipData 对象中。例如,提供纯文本,如下所示:

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        )
    )
}

为了允许拖动操作跨越应用的边界,DragAndDropTransferData 构造函数接受一个 flags 参数。在以下示例中,DRAG_FLAG_GLOBAL 常量指定数据可以从一个应用拖动到另一个应用

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        ),
        flags = View.DRAG_FLAG_GLOBAL
    )
}

DragAndDropTransferData 接受 Android View 系统支持的标志。有关可用标志的完整列表,请参阅 View 常量列表。

接收拖放数据

dragAndDropTarget 修饰符分配给可组合项,以使该可组合项能够接收拖放事件。该修饰符有两个参数:第一个参数充当过滤器,指定修饰符可以接受的数据类型;第二个参数通过回调传递数据。

请注意,回调实例应被 记住。以下代码段显示了如何记住回调

val callback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            // Parse received data
            return true
        }
    }
}

下一个代码段演示了如何处理拖放的纯文本

Modifier.dragAndDropTarget(
    shouldStartDragAndDrop = { event ->
        event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
    }, target = callback
)

如果事件已处理,回调函数应返回 true;如果事件被拒绝并且不传播到父组件,则返回 false

处理拖放事件

重写 DragAndDropTarget 接口中的回调,以观察拖放事件何时开始、结束或进入/退出组件,从而精确控制 UI 和应用的行为

object : DragAndDropTarget {
    override fun onStarted(event: DragAndDropEvent) {
        // When the drag event starts
    }

    override fun onEntered(event: DragAndDropEvent) {
        // When the dragged object enters the target surface
    }

    override fun onEnded(event: DragAndDropEvent) {
        // When the drag event stops
    }

    override fun onExited(event: DragAndDropEvent) {
        // When the dragged object exits the target surface
    }

    override fun onDrop(event: DragAndDropEvent): Boolean = true
}

其他资源

Codelab:Compose 中的拖放功能