Kéo và thả

Jetpack Compose hỗ trợ thao tác kéo và thả bằng 2 đố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éo
  • dragAndDropTarget: 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 của bạn, hãy tạo một thành phần kết hợp hình ảnh rồi thêm đối tượng sửa đổi 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 rồi 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ả.

Đối tượng sửa đổi cho phép các ứng dụng chia sẻ dữ liệu giữa 2 hoặc nhiều thành phần kết hợp bằng cách sử dụng ClipData, có thể tương tác với hoạt động triển khai View.

Bắt đầu một sự kiện kéo

Để bật các 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. Đối tượng này sẽ lấy hàm tạm ngưng làm tham số. Hàm này xác định hoạt động tương tác của người dùng mà bắt đầu thao tác kéo. Đối tượng sửa đổi dragAndDropSource chờ cho đến khi nhận được sự kiện nhập con trỏ, sau đó thực thi lambda đã truyền đến trình xử lý sự kiện. Sử dụng lambda để phát hiện nhiều sự kiện đầu vào, chẳng hạn như nhấn hoặc nhấn và giữ. Để biết thêm thông tin, hãy xem bài viết Nhập con trỏ trong Compose.

Sự kiện nhập con trỏ thường là thao tác nhấn và giữ được triển khai như sau:

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

Để bắt đầu một phiên kéo và thả, hãy gọi hàm startTransfer(). Trong phạm vi 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ộ, v.v., nhưng tất cả đều cần được gói trong đối tượng ClipData. Cung cấp văn bản thuần tuý, chẳng hạn như sau:

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

Để cho phép thao tác kéo vượt qua đường viền 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 có thể kéo dữ liệu từ ứng dụng này sang ứng dụng khác:

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

DragAndDropTransferData chấp nhận các cờ được hệ thống Khung hiển thị 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 về tình trạng sụt giảm

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 và tham số thứ hai phân phối dữ liệu trong lệnh gọi lại.

Lưu ý rằng cần phải ghi nhớ thực thể của lệnh 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
        }
    }
}

Đoạn mã tiếp theo minh hoạ cách xử lý văn bản thuần tuý bị bỏ qua:

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

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 đè các 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 nhập hoặc thoát khỏi một thành phần nhằm điều khiển 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