Jetpack Compose 使用两个修饰符支持拖放
dragAndDropSource
:指定一个可组合项作为拖动手势的起点dragAndDropTarget
:指定一个可组合项,用于接收放置的数据
例如,要允许用户在您的应用中拖动图像,请创建一个图像可组合项并添加 dragAndDropSource
修饰符。要设置放置目标,请创建另一个图像可组合项并添加 dragAndDropTarget
修饰符。
这些修饰符可以应用于多个拖动源和多个放置目标。
这些修饰符使应用能够使用 ClipData
在两个或多个可组合项之间共享数据,该数据与 View
实现具有互操作性。
开始拖动事件
要在组件内部启用拖动事件,请添加 dragAndDropSource
修饰符,该修饰符将一个挂起函数作为参数。该函数定义了启动拖动操作的用户交互。 dragAndDropSource
修饰符会等待直到收到指针输入事件,然后执行传递给事件处理程序的 lambda 表达式。使用 lambda 表达式检测各种输入事件,例如点击或长按。有关更多信息,请参阅 Compose 中的指针输入。
指针输入事件通常是如下实现的长按
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { // Transfer data here. }) }
要开始拖放会话,请调用 startTransfer()
函数。在此范围内,使用 DragAndDropTransferData
表示可传输数据。数据可以是远程 URI、剪贴板上的富文本数据、本地文件或更多内容,但它们都需要包装在 ClipData
对象中。例如,提供纯文本,如下所示
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { startTransfer( DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) ) }) }
要允许拖动操作跨越应用边界,DragAndDropTransferData
构造函数接受一个 flags
参数。在以下示例中,DRAG_FLAG_GLOBAL
常量指定数据可以从一个应用拖动到另一个应用
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { startTransfer( 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 中的拖放