拖放
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Jetpack Compose 支持使用以下两个修饰符进行拖放:
例如,如需让用户能够在您的应用中拖动图片,请创建一个图片可组合项并添加 dragAndDropSource
修饰符。如需设置拖放目标,请再创建一个图片可组合项并添加 dragAndDropTarget
修饰符。
修饰符可应用于多个拖动来源和多个拖放目标。
借助这些修饰符,应用可以使用 ClipData
在两个或更多可组合项之间共享数据,而 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
}
}
}
如需接受来自其他应用的数据,请使用 requestDragAndDropPermission
启用接收功能,并在完成后释放该功能:
val externalAppCallback = remember {
object : DragAndDropTarget {
override fun onDrop(event: DragAndDropEvent): Boolean {
val permission =
activity.requestDragAndDropPermissions(event.toAndroidDragEvent())
// Parse received data
permission?.release()
return true
}
}
}
请务必注意,从 Compose 回调返回的 DragAndDropEvent
与 requestDragAndDropPermission
方法预期的 DragAndDropEvent
不同,因此您需要先对参数调用 toAndroidDragEvent()
扩展函数,然后才能将其传递给权限请求。
以下代码段演示了如何处理丢弃的纯文本:
Modifier.dragAndDropTarget(
shouldStartDragAndDrop = { event ->
event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
}, target = callback // or externalAppCallback
)
如果事件已被使用,回调函数应返回 true
;如果事件被拒绝且未传播到父级组件,则应返回 false
。
处理拖放事件
替换 DragAndDropTarget
接口中的回调,以便监控拖放事件的开始、结束或进入或退出组件的时间,从而精确控制界面和应用的行为:
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 中拖放
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-27。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-08-27。"],[],[],null,["Jetpack Compose supports drag and drop with two modifiers:\n\n- [`dragAndDropSource`](/reference/kotlin/androidx/compose/foundation/draganddrop/package-summary#(androidx.compose.ui.Modifier).dragAndDropSource(kotlin.Function1)): Specifies a composable as the starting point of the drag gesture\n- [`dragAndDropTarget`](/reference/kotlin/androidx/compose/foundation/draganddrop/package-summary#(androidx.compose.ui.Modifier).dragAndDropTarget(kotlin.Function1,androidx.compose.ui.draganddrop.DragAndDropTarget)): Specifies a composable that accepts the dropped data\n\nFor example, to enable users to drag an image in your app, create an image\ncomposable and add the `dragAndDropSource` modifier. To set up a drop target,\ncreate another image composable and add the `dragAndDropTarget` modifier.\n\nThe modifiers can be applied to multiple drag sources and multiple drop targets.\n\nThe modifiers enable apps to share data between two or more composables using\n[`ClipData`](/reference/kotlin/android/content/ClipData), which is interoperable with [`View`](/reference/kotlin/android/view/View) implementations.\n| **Note:** Drag and drop is different from [pick up and\n| move](https://m3.material.io/foundations/interaction/gestures#af76950f-a24c-43bd-bfcd-a9eb15768142), a common list pattern.\n\nSpecify a drag source\n\nTo enable drag events inside a component, add the `dragAndDropSource` modifier.\nThis takes a function as a parameter. Inside this function, use\n[`DragAndDropTransferData`](/reference/kotlin/androidx/compose/ui/draganddrop/DragAndDropTransferData) to represent the transferable data. The data can\nbe a remote URI, rich text data on the clipboard, a local file, or more, but\nthey all need to be wrapped in a `ClipData` object. Provide plain text, for\nexample, as follows:\n\n\n```kotlin\nModifier.dragAndDropSource { _ -\u003e\n DragAndDropTransferData(\n ClipData.newPlainText(\n \"image Url\", url\n )\n )\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L45-L51\n```\n\n\u003cbr /\u003e\n\nTo allow the drag action to cross the borders of the app, the\n`DragAndDropTransferData` constructor accepts a `flags` argument. In the\nfollowing example, the [`DRAG_FLAG_GLOBAL`](/reference/kotlin/android/view/View#drag_flag_global) constant specifies that data can\nbe dragged from one app into another:\n\n\n```kotlin\nModifier.dragAndDropSource { _ -\u003e\n DragAndDropTransferData(\n ClipData.newPlainText(\n \"image Url\", url\n ),\n flags = View.DRAG_FLAG_GLOBAL\n )\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L55-L62\n```\n\n\u003cbr /\u003e\n\n`DragAndDropTransferData` accepts flags supported by the Android View system.\nSee the list of [View](/reference/kotlin/android/view/View) constants for an exhaustive list of available flags.\n\nReceive drop data\n\nAssign the `dragAndDropTarget` modifier to a composable to enable the composable\nto receive drag-and-drop events. The modifier has two parameters: the first acts\nas a filter and specifies the kind of data the modifier can accept, and the\nsecond delivers the data in a callback.\n\nNote that the callback instance should be *remembered*. The following snippet\nshows how to remember the callback:\n\n\n```kotlin\nval callback = remember {\n object : DragAndDropTarget {\n override fun onDrop(event: DragAndDropEvent): Boolean {\n // Parse received data\n return true\n }\n }\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L66-L73\n```\n\n\u003cbr /\u003e\n\nTo accept data from other apps, use the [`requestDragAndDropPermission`](/reference/android/app/Activity#requestDragAndDropPermissions(android.view.DragEvent)) to\nenable the reception, and release it once done:\n\n\n```kotlin\nval externalAppCallback = remember {\n object : DragAndDropTarget {\n override fun onDrop(event: DragAndDropEvent): Boolean {\n val permission =\n activity.requestDragAndDropPermissions(event.toAndroidDragEvent())\n // Parse received data\n permission?.release()\n return true\n }\n }\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L78-L88\n```\n\n\u003cbr /\u003e\n\nIt's important to remember that the `DragAndDropEvent` returned from the Compose\ncallback is different from the one expected by the `requestDragAndDropPermission`\nmethod, so you need to call the [`toAndroidDragEvent()`](/reference/kotlin/androidx/compose/ui/draganddrop/DragAndDropEvent#(androidx.compose.ui.draganddrop.DragAndDropEvent).toAndroidDragEvent()) extension function on the parameter before\npassing it to the permission request.\n\nThe next snippet demonstrates how to handle dropped plain text:\n\n\n```kotlin\nModifier.dragAndDropTarget(\n shouldStartDragAndDrop = { event -\u003e\n event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)\n }, target = callback // or externalAppCallback\n)https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L93-L97\n```\n\n\u003cbr /\u003e\n\nThe callback function should return `true` if the event is consumed, or `false`\nif the event is refused and does not propagate to the parent component.\n\nHandle drag-and-drop events\n\nOverride callbacks in the [`DragAndDropTarget`](/reference/kotlin/androidx/compose/ui/draganddrop/DragAndDropTarget) interface to observe when a\ndrag-and-drop event starts, ends, or enters or exits a component for precise\ncontrol of the UI and the app's behavior:\n\n\n```kotlin\nobject : DragAndDropTarget {\n override fun onStarted(event: DragAndDropEvent) {\n // When the drag event starts\n }\n\n override fun onEntered(event: DragAndDropEvent) {\n // When the dragged object enters the target surface\n }\n\n override fun onEnded(event: DragAndDropEvent) {\n // When the drag event stops\n }\n\n override fun onExited(event: DragAndDropEvent) {\n // When the dragged object exits the target surface\n }\n\n override fun onDrop(event: DragAndDropEvent): Boolean = true\n}https://github.com/android/snippets/blob/5673ffc60b614daf028ee936227128eb8c4f9781/compose/snippets/src/main/java/com/example/compose/snippets/draganddrop/DragAndDropSnippets.kt#L101-L119\n```\n\n\u003cbr /\u003e\n\nAdditional resources\n\nCodelab: [Drag and drop in Compose](/codelabs/codelab-dnd-compose)"]]