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
@ExperimentalFoundationApi
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
@ExperimentalFoundationApi
Modifier.dragAndDropTarget(
    shouldStartDragAndDrop: (startEvent: DragAndDropEvent) -> Boolean,
    target: DragAndDropTarget
)

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

Cmn

Extension functions

dragAndDropSource

@ExperimentalFoundationApi
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

@ExperimentalFoundationApi
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

@ExperimentalFoundationApi
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.