Przeciągnij i upuść

W Jetpack Compose możesz przeciągać i upuszczać elementy za pomocą dwóch modyfikatorów:

  • dragAndDropSource: określa funkcję kompozycyjną jako punkt początkowy gestu przeciągania
  • dragAndDropTarget: określa element kompozycyjny, który akceptuje usunięte dane.

Na przykład, aby umożliwić użytkownikom przeciąganie obrazu w aplikacji, utwórz obraz z możliwością komponowania obrazu i dodaj modyfikator dragAndDropSource. Aby skonfigurować docelową wartość spadku, utwórz inny kompozycyjny obraz i dodaj modyfikator dragAndDropTarget.

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

Modyfikatory umożliwiają aplikacjom udostępnianie danych między 2 lub większą liczbą funkcji kompozycyjnych przy użyciu funkcji ClipData, która współpracuje z implementacjami View.

Rozpoczynanie zdarzenia przeciągania

Aby umożliwić przeciąganie zdarzeń wewnątrz komponentu, dodaj modyfikator dragAndDropSource, który przyjmuje funkcję zawieszania jako parametr. Ta funkcja określa interakcję użytkownika, która rozpoczyna operację przeciągania. Modyfikator dragAndDropSource czeka na otrzymanie zdarzenia wejściowego wskaźnika, a następnie wykonuje funkcję lambda przekazaną do modułu obsługi zdarzeń. Funkcja lambda umożliwia wykrywanie różnych zdarzeń związanych z wprowadzaniem danych, np. dotknięć lub przytrzymania. Więcej informacji znajdziesz w artykule Dane wejściowe wskaźnika w Compose.

Zdarzenie danych wejściowych wskaźnika jest zwykle długie i naciśnięte w ten sposób:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        // Transfer data here.
    })
}

Aby rozpocząć sesję przeciągania i upuszczania, wywołaj funkcję startTransfer(). W tym zakresie do reprezentowania danych dostępnych do przeniesienia użyj nazwy DragAndDropTransferData. Mogą to być zdalny identyfikator URI, sformatowany tekst w schowku, plik lokalny lub inny element, ale wszystkie muszą być ujęte w obiekt ClipData. Podaj zwykły tekst, na przykład w taki sposób:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                )
            )
        )
    })
}

Aby umożliwić przeciąganie po granicach aplikacji, konstruktor DragAndDropTransferData akceptuje argument flags. W tym przykładzie stała DRAG_FLAG_GLOBAL określa, że dane mogą być przeciągane z jednej aplikacji do drugiej:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                ),
                flags = View.DRAG_FLAG_GLOBAL
            )
        )
    })
}

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

Odbieranie danych o utraconych danych

Przypisz modyfikator dragAndDropTarget do funkcji kompozycyjnej, aby umożliwić tej funkcji przyjmowanie zdarzeń przeciągania i upuszczania. Modyfikator ma 2 parametry: pierwszy działa jak filtr i określa rodzaj danych, które może przyjmować, a drugi dostarcza dane w wywołaniu zwrotnym.

Wystąpienie wywołania zwrotnego powinno być zapamiętane. Z tego fragmentu dowiesz się, jak zapamiętać wywołanie zwrotne:

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

Następny fragment kodu pokazuje, jak postępować w przypadku upuszczenia zwykłego tekstu:

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

Funkcja wywołania zwrotnego powinna zwracać wartość true, jeśli zdarzenie zostało przeanalizowane, lub false, jeśli zostanie ono odrzucone i nie zostanie rozpowszechnione w komponencie nadrzędnym.

Obsługa zdarzeń przeciągania i upuszczania

Zastępuj wywołania zwrotne w interfejsie DragAndDropTarget, aby obserwować, kiedy zdarzenie przeciągania i upuszczania rozpoczyna się, kończy, otwiera lub opuszcza komponent, co zapewnia precyzyjną kontrolę nad interfejsem i działaniem aplikacji:

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

Ćwiczenie w programowaniu: przeciąganie i upuszczanie w narzędziu Compose