Arrastrar y soltar

Jetpack Compose admite arrastrar y soltar con dos modificadores:

  • dragAndDropSource: Especifica un elemento componible como el punto de partida del gesto de arrastre.
  • dragAndDropTarget: Especifica un elemento componible que acepta los datos que se dejan caer.

Por ejemplo, para permitir que los usuarios arrastren una imagen en tu app, crea un elemento componible de imagen y agrega el modificador dragAndDropSource. Para configurar un destino de caída, crea otro elemento componible de imagen y agrega el modificador dragAndDropTarget.

Los modificadores se pueden aplicar a varias fuentes de arrastre y varios destinos de caída.

Los modificadores permiten que las apps compartan datos entre dos o más elementos componibles con ClipData, que es interoperable con las implementaciones de View.

Especifica una fuente de arrastre

Para habilitar los eventos de arrastre dentro de un componente, agrega el modificador dragAndDropSource. Esta función toma una función como parámetro. Dentro de esta función, usa DragAndDropTransferData para representar los datos transferibles. Los datos pueden ser un URI remoto, datos de texto enriquecido en el portapapeles, un archivo local o más, pero todos deben estar unidos en un objeto ClipData. Proporciona texto sin formato, por ejemplo, de la siguiente manera:

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        )
    )
}

Para permitir que la acción de arrastre cruce los límites de la app, el constructor DragAndDropTransferData acepta un argumento flags. En el siguiente ejemplo, la constante DRAG_FLAG_GLOBAL especifica que los datos se pueden arrastrar de una app a otra:

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        ),
        flags = View.DRAG_FLAG_GLOBAL
    )
}

DragAndDropTransferData acepta marcas compatibles con el sistema de View de Android. Consulta la lista de constantes de View para obtener una lista exhaustiva de las marcas disponibles.

Cómo recibir datos de lanzamiento

Asigna el modificador dragAndDropTarget a un elemento componible para que este pueda recibir eventos de arrastrar y soltar. El modificador tiene dos parámetros: el primero actúa como un filtro y especifica el tipo de datos que puede aceptar el modificador, y el segundo entrega los datos en una devolución de llamada.

Ten en cuenta que se debe recordar la instancia de devolución de llamada. En el siguiente fragmento, se muestra cómo recordar la devolución de llamada:

val callback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            // Parse received data
            return true
        }
    }
}

Para aceptar datos de otras apps, usa requestDragAndDropPermission para habilitar la recepción y suéltala cuando termines:

val externalAppCallback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            val permission =
                activity.requestDragAndDropPermissions(event.toAndroidDragEvent())
            // Parse received data
            permission?.release()
            return true
        }
    }
}

Es importante recordar que el DragAndDropEvent que se muestra desde la devolución de llamada de Compose es diferente del que espera el método requestDragAndDropPermission, por lo que debes llamar a la función de extensión toAndroidDragEvent() en el parámetro antes de pasarlo a la solicitud de permiso.

En el siguiente fragmento, se muestra cómo controlar el texto sin formato que se suelta:

Modifier.dragAndDropTarget(
    shouldStartDragAndDrop = { event ->
        event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
    }, target = callback // or externalAppCallback
)

La función de devolución de llamada debe mostrar true si se consume el evento o false si se rechaza y no se propaga al componente superior.

Cómo controlar eventos de arrastrar y soltar

Anula las devoluciones de llamada en la interfaz DragAndDropTarget para observar cuándo comienza, termina o entra o sale un evento de arrastrar y soltar para controlar con precisión la IU y el comportamiento de la app:

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
}

Recursos adicionales

Codelab: Cómo arrastrar y soltar en Compose