androidx.compose.foundation.draganddrop

Interfaces

DragAndDropSourceScope

A scope that allows for the detection of the start of a drag and drop gesture, and subsequently starting a drag and drop session.

Cmn

Extension functions summary

Modifier

A Modifier that allows an element it is applied to to be treated like a source for drag and drop operations.

android
Modifier
Modifier.dragAndDropSource(
    drawDragDecoration: DrawScope.() -> Unit,
    block: suspend DragAndDropSourceScope.() -> Unit
)

A Modifier that allows an element it is applied to to be treated like a source for drag and drop operations.

Cmn
Modifier
Modifier.dragAndDropTarget(
    shouldStartDragAndDrop: (startEvent: DragAndDropEvent) -> Boolean,
    target: DragAndDropTarget
)

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

Cmn

Extension functions

dragAndDropSource

fun Modifier.dragAndDropSource(block: suspend DragAndDropSourceScope.() -> Unit): Modifier

A Modifier that allows an element it is applied to to be treated like a source for drag and drop operations. It displays the element dragged as a drag shadow.

Learn how to use Modifier.dragAndDropSource:

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.draganddrop.dragAndDropSource
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draganddrop.DragAndDropTransferData
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

val label = remember { "Drag me" }
Box(
    modifier =
        modifier
            .dragAndDropSource {
                detectTapGestures(
                    onLongPress = {
                        startTransfer(
                            DragAndDropTransferData(
                                clipData = ClipData.newPlainText(label, label),
                                flags = View.DRAG_FLAG_GLOBAL,
                            )
                        )
                    }
                )
            }
            .border(
                border =
                    BorderStroke(
                        width = 4.dp,
                        brush = Brush.linearGradient(listOf(Color.Magenta, Color.Magenta))
                    ),
                shape = RoundedCornerShape(16.dp)
            )
            .padding(24.dp),
) {
    Text(modifier = Modifier.align(Alignment.Center), text = label)
}
Parameters
block: suspend DragAndDropSourceScope.() -> Unit

A lambda with a DragAndDropSourceScope as a receiver which provides a PointerInputScope to detect the drag gesture, after which a drag and drop gesture can be started with DragAndDropSourceScope.startTransfer.

dragAndDropSource

fun Modifier.dragAndDropSource(
    drawDragDecoration: DrawScope.() -> Unit,
    block: suspend DragAndDropSourceScope.() -> Unit
): Modifier

A Modifier that allows an element it is applied to to be treated like a source for drag and drop operations.

Learn how to use Modifier.dragAndDropSource while providing a custom drag shadow:

import androidx.compose.foundation.background
import androidx.compose.foundation.draganddrop.dragAndDropSource
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

Box(
    modifier =
        Modifier.size(56.dp).background(color = color).dragAndDropSource(
            drawDragDecoration = { drawRect(color) },
        ) {
            detectTapGestures(onLongPress = { startTransfer(color.toDragAndDropTransfer()) })
        }
)
Parameters
drawDragDecoration: DrawScope.() -> Unit

provides the visual representation of the item dragged during the drag and drop gesture.

block: suspend DragAndDropSourceScope.() -> Unit

A lambda with a DragAndDropSourceScope as a receiver which provides a PointerInputScope to detect the drag gesture, after which a drag and drop gesture can be started with DragAndDropSourceScope.startTransfer.

dragAndDropTarget

fun Modifier.dragAndDropTarget(
    shouldStartDragAndDrop: (startEvent: DragAndDropEvent) -> Boolean,
    target: DragAndDropTarget
): Modifier

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

Learn how to use Modifier.dragAndDropTarget to receive drag and drop events from inside your app or from other apps:

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.draganddrop.dragAndDropTarget
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draganddrop.DragAndDropEvent
import androidx.compose.ui.draganddrop.DragAndDropTarget
import androidx.compose.ui.draganddrop.mimeTypes
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

val validMimeTypePrefixes = remember {
    setOf(
        ClipDescription.MIMETYPE_TEXT_INTENT,
        "image/",
        "text/",
        "video/",
        "audio/",
    )
}
var backgroundColor by remember { mutableStateOf(Color.Transparent) }
Box(
    modifier =
        Modifier.fillMaxSize()
            .dragAndDropTarget(
                shouldStartDragAndDrop = accept@{ startEvent ->
                        val hasValidMimeType =
                            startEvent.mimeTypes().any { eventMimeType ->
                                validMimeTypePrefixes.any(eventMimeType::startsWith)
                            }
                        hasValidMimeType
                    },
                target =
                    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
                        }
                    },
            )
            .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
            )
    }
}
Parameters
shouldStartDragAndDrop: (startEvent: DragAndDropEvent) -> Boolean

Allows the Composable to decide if it wants to receive from a given drag and drop session by inspecting the DragAndDropEvent that started the session.

target: DragAndDropTarget

The DragAndDropTarget that will receive events for a given drag and drop session.

All drag and drop target modifiers in the hierarchy will be given an opportunity to participate in a given drag and drop session via shouldStartDragAndDrop.