Compose Modifier

dragAndDropTarget

A modifier that allows for receiving from a drag and drop gesture.

TextDragAndDropTargetSample

@Sampled
@Composable
fun TextDragAndDropTargetSample(
    eventSummary: String?,
    onDragAndDropEventDropped: (DragAndDropEvent) -> Unit,
) {
    val validMimeTypePrefixes = remember {
        setOf(ClipDescription.MIMETYPE_TEXT_INTENT, "image/", "text/", "video/", "audio/")
    }
    var backgroundColor by remember { mutableStateOf(Color.Transparent) }
    val dragAndDropTarget = remember {
        object : DragAndDropTarget {
            override fun onStarted(event: DragAndDropEvent) {
                backgroundColor = Color.DarkGray.copy(alpha = 0.2f)
            }

            override fun onDrop(event: DragAndDropEvent): Boolean {
                onDragAndDropEventDropped(event)
                return true
            }

            override fun onEnded(event: DragAndDropEvent) {
                backgroundColor = Color.Transparent
            }
        }
    }
    Box(
        modifier =
            Modifier.fillMaxSize()
                .dragAndDropTarget(
                    shouldStartDragAndDrop = accept@{ startEvent ->
                            val hasValidMimeType =
                                startEvent.mimeTypes().any { eventMimeType ->
                                    validMimeTypePrefixes.any(eventMimeType::startsWith)
                                }
                            hasValidMimeType
                        },
                    target = dragAndDropTarget,
                )
                .background(backgroundColor)
                .border(width = 4.dp, color = Color.Magenta, shape = RoundedCornerShape(16.dp))
    ) {
        when (eventSummary) {
            null -> Text(modifier = Modifier.align(Alignment.Center), text = "Drop anything here")
            else ->
                Text(
                    modifier =
                        Modifier.padding(horizontal = 16.dp, vertical = 24.dp)
                            .verticalScroll(rememberScrollState()),
                    text = eventSummary,
                )
        }
    }
}

private fun DragAndDropEvent.summary() =
    (0 until toAndroidDragEvent().clipData.itemCount)
        .map(toAndroidDragEvent().clipData::getItemAt)
        .withIndex()
        .joinToString(separator = "\n\n") { (index, clipItem) ->
            val mimeTypes =
                (0 until toAndroidDragEvent().clipData.description.mimeTypeCount).joinToString(
                    separator = ", ",
                    transform = toAndroidDragEvent().clipData.description::getMimeType,
                )
            listOfNotNull(
                    "index: $index",
                    "mimeTypes: $mimeTypes",
                    clipItem.text?.takeIf(CharSequence::isNotEmpty)?.let { "text: $it" },
                    clipItem.htmlText?.takeIf(CharSequence::isNotEmpty)?.let { "html text: $it" },
                    clipItem.uri?.toString()?.let { "uri: $it" },
                    clipItem.intent?.let {
                        "intent: action - ${it.action}; extras size: ${it.extras?.size()}"
                    },
                )
                .joinToString(separator = "\n")
        }
Jetpack Compose beyond MaterialFree components, screens and templates for apps that don’t look like Google’s. Copy them into your app, or let your coding agent add them.Browse for free

Content updated: