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 mục tiêu thả, hãy tạo một mục tiêu khác thành phần kết hợp hình ảnh 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ả.

Đối tượng sửa đổi cho phép các ứ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, có thể tương tác với các phương thức 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, lấy hàm tạm ngưng làm tham số. Hàm xác định người dùng tương tác bắt đầu thao tác kéo. Đối tượng sửa đổi dragAndDropSource đợi cho đến khi nhận được sự kiện nhập con trỏ rồi thực thi hàm lambda được chuyể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, ví dụ: nhấn hoặc nhấn và giữ. Để biết thêm thông tin, hãy xem phần Con trỏ dữ liệu đầu vào 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 này 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ả chúng đều cần được gói trong một Đố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 chấp nhận đối số flags. Trong ví dụ sau đây, 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 {
    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ợ. Xem danh sách hằng số View để xem danh sách đầy đủ các cờ hiện có.

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 để bật 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 có vai trò như 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à giây thì 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 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 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 để quyền kiểm soát 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