Przeciągnij i upuść

Jetpack Compose obsługuje przeciąganie i upuszczanie z 2 modyfikatorami:

  • dragAndDropSource: określa komponent jako punkt początkowy gestu przeciągania.
  • dragAndDropTarget: określa komponent, który przyjmuje dane z przeciągniętego elementu.

Aby na przykład umożliwić użytkownikom przeciąganie obrazu w aplikacji, utwórz komponent obrazu i dodaj modyfikator dragAndDropSource. Aby skonfigurować miejsce docelowe, utwórz kolejny element kompozytowy obrazu i dodaj modyfikator dragAndDropTarget.

Modyfikatory można stosować do wielu źródeł przeciągania i wielu miejsc docelowych.

Modyfikatory umożliwiają aplikacjom udostępnianie danych między co najmniej 2 komponowalnymi za pomocą ClipData, który jest interoperacyjny z implementacjami View.

Określ źródło przeciągania

Aby umożliwić zdarzenia przeciągania wewnątrz komponentu, dodaj modyfikator dragAndDropSource. Funkcja ta przyjmuje funkcję jako parametr. W ramach tej funkcji użyj wartości DragAndDropTransferData, aby reprezentować dane do przeniesienia. Dane mogą być identyfikatorem URI zdalnym, danymi tekstu formatowanego w schowku, plikiem lokalnym lub czymś innym, ale wszystkie muszą być zapakowane w obiekt ClipData. Podaj zwykły tekst, na przykład:

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

Aby umożliwić działanie przeciągania przekraczanie granic aplikacji, konstruktor DragAndDropTransferData przyjmuje argument flags. W tym przykładzie stała DRAG_FLAG_GLOBAL określa, że dane można przeciągać z jednej aplikacji do drugiej:

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

DragAndDropTransferData obsługuje flagi obsługiwane przez system Android View. Pełną listę dostępnych flag znajdziesz na liście stałych View.

Odbieranie danych o wypadkach

Przypisz modyfikator dragAndDropTarget do komponentu, aby umożliwić mu otrzymywanie zdarzeń przeciągania i upuszczania. Modyfikator ma 2 parametry: pierwszy działa jako filtr i określa rodzaj danych, które może akceptować, a drugi przekazuje dane w wywołaniu zwrotnym.

Pamiętaj, że instancja wywołania zwrotnego powinna być zapamiętana. Ten fragment kodu pokazuje, jak zapamiętać wywołanie zwrotne:

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

Aby akceptować dane z innych aplikacji, użyj przycisku requestDragAndDropPermission, aby włączyć odbiór, a potem go zwolnić:

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

Pamiętaj, że parametr DragAndDropEvent zwracany przez metodę Compose w wywołaniu zwrotnym różni się od tego, którego oczekuje metoda requestDragAndDropPermission. Przed przekazaniem go do żądania uprawnień musisz wywołać funkcję rozszerzenia toAndroidDragEvent().

Ten fragment kodu pokazuje, jak obsługiwać wklejony tekst:

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

Funkcja wywołania zwrotnego powinna zwracać wartość true, jeśli zdarzenie zostało przetworzone, lub false, jeśli zdarzenie zostało odrzucone i nie zostało przekazane do komponentu nadrzędnego.

Obsługa zdarzeń przeciągania i upuszczania

Aby dokładnie kontrolować interfejs użytkownika i zachowanie aplikacji, możesz zastąpić funkcje zwracane przez interfejs DragAndDropTarget, aby obserwować, kiedy zdarzenie przeciągania i upuszczania rozpoczyna się, kończy się lub wchodzi do komponentu lub z niego wychodzi:

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
}

Dodatkowe materiały

Codelab: przeciąganie i upuszczanie w Compose