Jetpack Compose obsługuje przeciąganie i upuszczanie za pomocą 2 modyfikatorów:
dragAndDropSource: określa element kompozycyjny jako punkt początkowy gestu przeciągania.dragAndDropTarget: określa element kompozycyjny, który akceptuje upuszczone dane.
Aby na przykład umożliwić użytkownikom przeciąganie obrazu w aplikacji, utwórz funkcję kompozycyjną obrazu i dodaj modyfikator dragAndDropSource. Aby skonfigurować miejsce upuszczenia, utwórz kolejną funkcję kompozycyjną obrazu i dodaj modyfikator dragAndDropTarget.
Modyfikatory można stosować do wielu źródeł przeciągania i wielu miejsc docelowych upuszczania.
Modyfikatory umożliwiają aplikacjom udostępnianie danych między co najmniej 2 komponentami za pomocą ClipData, który współdziała z implementacjami View.
Określanie źródła przeciągania
Aby włączyć zdarzenia przeciągania w komponencie, dodaj modyfikator dragAndDropSource.
Ta funkcja przyjmuje funkcję jako parametr. W tej funkcji użyj DragAndDropTransferData, aby reprezentować dane, które można przenieść. Dane mogą być zdalnym identyfikatorem URI, tekstem sformatowanym w schowku, plikiem lokalnym lub innym elementem, ale wszystkie muszą być opakowane w obiekt ClipData. Podaj zwykły tekst, na przykład w ten sposób:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
Aby umożliwić przeciąganie poza granice aplikacji, konstruktor DragAndDropTransferData akceptuje 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 akceptuje flagi obsługiwane przez system Android View.
Pełną listę dostępnych flag znajdziesz na liście stałych View.
Odbieranie danych o upuszczeniu
Przypisz modyfikator dragAndDropTarget do funkcji kompozycyjnej, aby umożliwić jej odbieranie zdarzeń przeciągania i upuszczania. Modyfikator ma 2 parametry: pierwszy działa jako filtr i określa rodzaj danych, które modyfikator może akceptować, a drugi dostarcza dane w wywołaniu zwrotnym.
Pamiętaj, że instancja wywołania zwrotnego powinna być zapamiętana. Poniższy 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 requestDragAndDropPermission, aby włączyć odbiór, i zwolnij, gdy skończysz:
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 obiekt DragAndDropEvent zwracany przez wywołanie zwrotne Compose różni się od obiektu oczekiwanego przez metodę requestDragAndDropPermission, dlatego przed przekazaniem parametru do prośby o uprawnienia musisz wywołać funkcję rozszerzenia toAndroidDragEvent().
Poniższy fragment kodu pokazuje, jak obsługiwać upuszczony zwykły 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 wykorzystane, lub false, jeśli zdarzenie zostało odrzucone i nie zostało przekazane do komponentu nadrzędnego.
Obsługa zdarzeń przeciągania i upuszczania
Zastąp wywołania zwrotne w interfejsie DragAndDropTarget, aby obserwować, kiedy zdarzenie przeciągania i upuszczania się rozpoczyna, kończy lub wchodzi do komponentu albo go opuszcza. Pozwoli to na precyzyjne kontrolowanie interfejsu i zachowania 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 Codelabs: przeciągnij i upuść w Compose