Jetpack Compose hỗ trợ tính năng kéo và thả bằng hai đối tượng sửa đổi:
dragAndDropSource
: Chỉ định một thành phần kết hợp 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 đã 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 thành phần kết hợp hình ảnh và thêm đối tượng sửa đổi dragAndDropSource
. Để thiết lập mục tiêu 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 giữa hai hoặc nhiều thành phần kết hợp bằng cách sử dụng ClipData
. Đối tượng này có thể 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à một URI từ xa, dữ liệu văn bản đa dạng thức trên bảng nhớ tạm, một 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 tuý, 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
sẽ 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 (Thành phần hiển thị) để biết danh sách đầy đủ các cờ hiện có.
Nhận dữ liệu thả
Chỉ định đối tượng sửa đổi dragAndDropTarget
cho một thành phần kết hợp để cho phép thành phần kết hợp đó 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 phân phối dữ liệu trong lệnh gọi lại.
Lưu ý rằng bạn phải 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à phát hành 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 DragAndDropEvent
mà phương thức requestDragAndDropPermission
dự kiến, 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 tuý đã thả:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
Hàm gọi lại 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 một sự kiện kéo và thả bắt đầu, kết thúc hoặc vào hoặc thoát khỏi một thành phần nhằm 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