androidx.compose.foundation.draganddrop

Interfaces

DragAndDropSourceScope

This interface is deprecated. Replaced by a callback for obtain a transfer data,start detection is performed by Compose itself

android

Extension functions summary

Modifier

This function is deprecated. Replaced by overload with a callback for obtain a transfer data,start detection is performed by Compose itself

android
Modifier

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

Cmn
Modifier
@ExperimentalFoundationApi
Modifier.dragAndDropSource(
    drawDragDecoration: DrawScope.() -> Unit,
    block: suspend DragAndDropSourceScope.() -> Unit
)

This function is deprecated. Replaced by overload with a callback for obtain a transfer data,start detection is performed by Compose itself

android
Modifier
Modifier.dragAndDropSource(
    drawDragDecoration: DrawScope.() -> Unit,
    transferData: (Offset) -> DragAndDropTransferData?
)

A Modifier that allows an element it is applied 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

@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.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 { _ ->
                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(
    transferData: (Offset) -> DragAndDropTransferData?
): Modifier

A Modifier that allows an element it is applied 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.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 { _ ->
                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
transferData: (Offset) -> DragAndDropTransferData?

A function that receives the current offset of the drag operation and returns the DragAndDropTransferData to be transferred. If null is returned, the drag and drop transfer won't be started.

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.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) },
        ) { _ ->
            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.

dragAndDropSource

fun Modifier.dragAndDropSource(
    drawDragDecoration: DrawScope.() -> Unit,
    transferData: (Offset) -> DragAndDropTransferData?
): Modifier

A Modifier that allows an element it is applied 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.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) },
        ) { _ ->
            color.toDragAndDropTransfer()
        }
)
Parameters
drawDragDecoration: DrawScope.() -> Unit

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

transferData: (Offset) -> DragAndDropTransferData?

A function that receives the current offset of the drag operation and returns the DragAndDropTransferData to be transferred. If null is returned, the drag and drop transfer won't be started.

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) }
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
            )
    }
}
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.