Jetpack Compose hỗ trợ thao tác kéo và thả bằng hai đối tượng sửa đổi:
dragAndDropSource: Chỉ định một composable làm điểm bắt đầu của cử chỉ kéodragAndDropTarget: Chỉ định một thành phần kết hợp chấp nhận dữ liệu được thả
Ví dụ: để cho phép người dùng kéo hình ảnh trong ứng dụng, hãy tạo một composable hình ảnh và thêm modifier dragAndDropSource. Để thiết lập đích thả, hãy tạo một thành phần kết hợp hình ảnh khác và thêm đối tượng sửa đổi dragAndDropTarget.
Bạn có thể áp dụng đối tượng sửa đổi cho nhiều nguồn kéo và nhiều mục tiêu thả.
Các đối tượng sửa đổi cho phép ứng dụng chia sẻ dữ liệu được chia sẻ giữa hai hoặc nhiều thành phần kết hợp bằng cách sử dụng ClipData, có khả năng tương tác với các phương thức triển khai View.
Chỉ định nguồn kéo
Để bật sự kiện kéo bên trong một thành phần, hãy thêm đối tượng sửa đổi dragAndDropSource.
Hàm này lấy một hàm làm tham số. Bên trong hàm này, hãy sử dụng DragAndDropTransferData để biểu thị dữ liệu có thể chuyển. Dữ liệu có thể là URI từ xa, dữ liệu văn bản đa dạng thức trên bảng nhớ tạm, tệp cục bộ hoặc nhiều dữ liệu khác, nhưng tất cả đều cần được gói trong một đối tượng ClipData. Cung cấp văn bản thuần túy, ví dụ:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
Để cho phép thao tác kéo vượt qua ranh giới của ứng dụng, hàm khởi tạo DragAndDropTransferData chấp nhận đối số flags. Trong ví dụ sau, hằng số DRAG_FLAG_GLOBAL chỉ định rằng dữ liệu có thể được kéo từ ứng dụng này sang ứng dụng khác:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ), flags = View.DRAG_FLAG_GLOBAL ) }
DragAndDropTransferData chấp nhận các cờ được hệ thống Chế độ xem Android hỗ trợ.
Hãy xem danh sách hằng số View để biết danh sách đầy đủ các cờ có sẵn.
Nhận dữ liệu thả
Chỉ định modifier dragAndDropTarget cho một composable để cho phép composable đó nhận các sự kiện kéo và thả. Đối tượng sửa đổi có hai tham số: tham số đầu tiên đóng vai trò là bộ lọc và chỉ định loại dữ liệu mà đối tượng sửa đổi có thể chấp nhận, còn tham số thứ hai cung cấp dữ liệu trong một lệnh gọi lại.
Xin lưu ý rằng bạn nên ghi nhớ thực thể gọi lại. Đoạn mã sau đây cho biết cách ghi nhớ lệnh gọi lại:
val callback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { // Parse received data return true } } }
Để chấp nhận dữ liệu từ các ứng dụng khác, hãy sử dụng requestDragAndDropPermission để bật tính năng nhận và giải phóng dữ liệu sau khi hoàn tất:
val externalAppCallback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { val permission = activity.requestDragAndDropPermissions(event.toAndroidDragEvent()) // Parse received data permission?.release() return true } } }
Điều quan trọng cần nhớ là DragAndDropEvent được trả về từ lệnh gọi lại Compose khác với lệnh gọi lại mà phương thức requestDragAndDropPermission mong đợi, vì vậy, bạn cần gọi hàm mở rộng toAndroidDragEvent() trên tham số trước khi truyền tham số đó đến yêu cầu cấp quyền.
Đoạn mã tiếp theo minh hoạ cách xử lý văn bản thuần túy được thả:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
Hàm callback sẽ trả về true nếu sự kiện được sử dụng hoặc false nếu sự kiện bị từ chối và không truyền đến thành phần mẹ.
Xử lý sự kiện kéo và thả
Ghi đè lệnh gọi lại trong giao diện DragAndDropTarget để quan sát thời điểm sự kiện kéo và thả bắt đầu, kết thúc hoặc vào hay thoát khỏi một thành phần để kiểm soát chính xác giao diện người dùng và hành vi của ứng dụng:
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 }
Tài nguyên khác
Lớp học lập trình: Kéo và thả trong Compose