Glisser-déposer

Jetpack Compose est compatible avec le glisser-déposer avec deux modificateurs:

  • dragAndDropSource: spécifie un composable comme point de départ du geste de glissement
  • dragAndDropTarget: spécifie un composable qui accepte les données abandonnées

Par exemple, pour permettre aux utilisateurs de faire glisser une image dans votre application, créez un composable d'image et ajoutez le modificateur dragAndDropSource. Pour configurer une cible de dépôt, créez un autre composable d'image et ajoutez le modificateur dragAndDropTarget.

Les modificateurs peuvent être appliqués à plusieurs sources de glisser-déposer et à plusieurs cibles de dépôt.

Les modificateurs permettent aux applications de partager des données entre deux composables ou plus à l'aide de ClipData, qui est interopérable avec les implémentations View.

Spécifier une source de déplacement

Pour activer les événements de glisser-déposer dans un composant, ajoutez le modificateur dragAndDropSource. Cette fonction utilise une fonction comme paramètre. Dans cette fonction, utilisez DragAndDropTransferData pour représenter les données transférables. Les données peuvent être un URI distant, des données de texte enrichi dans le presse-papiers, un fichier local, etc., mais elles doivent toutes être encapsulées dans un objet ClipData. Fournissez du texte brut, par exemple comme suit:

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

Pour permettre à l'action de glisser de franchir les limites de l'application, le constructeur DragAndDropTransferData accepte un argument flags. Dans l'exemple suivant, la constante DRAG_FLAG_GLOBAL spécifie que les données peuvent être glissées d'une application à une autre:

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

DragAndDropTransferData accepte les indicateurs compatibles avec le système Android View. Consultez la liste des constantes View pour obtenir une liste exhaustive des options disponibles.

Recevoir des données de diffusion

Attribuez le modificateur dragAndDropTarget à un composable pour lui permettre de recevoir des événements de glisser-déposer. Le modificateur comporte deux paramètres: le premier agit comme un filtre et spécifie le type de données que le modificateur peut accepter, et le second transmet les données dans un rappel.

Notez que l'instance de rappel doit être mémorisée. L'extrait de code suivant montre comment mémoriser le rappel:

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

Pour accepter les données d'autres applications, utilisez requestDragAndDropPermission pour activer la réception, puis libérez-la une fois terminée:

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

N'oubliez pas que le DragAndDropEvent renvoyé par le rappel Compose est différent de celui attendu par la méthode requestDragAndDropPermission. Vous devez donc appeler la fonction d'extension toAndroidDragEvent() sur le paramètre avant de le transmettre à la demande d'autorisation.

L'extrait de code suivant montre comment gérer le texte brut abandonné:

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

La fonction de rappel doit renvoyer true si l'événement est consommé, ou false si l'événement est refusé et ne se propage pas au composant parent.

Gérer les événements de glisser-déposer

Forcez les rappels dans l'interface DragAndDropTarget pour observer le début, la fin, l'entrée ou la sortie d'un événement de glisser-déposer dans un composant afin de contrôler précisément l'UI et le comportement de l'application:

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
}

Ressources supplémentaires

Atelier de programmation: Glisser-déposer dans Compose