ลากและวาง

Jetpack Compose รองรับการลากและวางด้วยตัวแก้ไข 2 รายการ ได้แก่

  • dragAndDropSource: ระบุ Composable เป็นจุดเริ่มต้นของท่าทางสัมผัสการลาก
  • dragAndDropTarget: ระบุ Composable ที่ยอมรับข้อมูลที่วาง

ตัวอย่างเช่น หากต้องการให้ผู้ใช้ลากรูปภาพในแอปได้ ให้สร้าง Composable รูปภาพและเพิ่มตัวแก้ไข dragAndDropSource หากต้องการตั้งค่าเป้าหมายการวาง ให้สร้าง Composable รูปภาพอีกรายการและเพิ่มตัวแก้ไข dragAndDropTarget

คุณสามารถใช้ตัวแก้ไขกับแหล่งที่มาของการลากหลายรายการและเป้าหมายการวางหลายรายการได้

ตัวปรับแต่งช่วยให้แอปแชร์ข้อมูลระหว่าง Composable ตั้งแต่ 2 รายการขึ้นไปได้โดยใช้ ClipData ซึ่งทำงานร่วมกับการใช้งาน View ได้

ระบุแหล่งที่มาของการลาก

หากต้องการเปิดใช้เหตุการณ์การลากภายในคอมโพเนนต์ ให้เพิ่มตัวแก้ไข dragAndDropSource ซึ่งจะใช้ฟังก์ชันเป็นพารามิเตอร์ ภายในฟังก์ชันนี้ ให้ใช้ DragAndDropTransferData เพื่อแสดงข้อมูลที่โอนได้ ข้อมูลอาจเป็น URI ระยะไกล, ข้อมูล Rich Text ในคลิปบอร์ด, ไฟล์ในเครื่อง หรืออื่นๆ แต่ทั้งหมดต้องรวมอยู่ในออบเจ็กต์ ClipData ระบุข้อความธรรมดา เช่น

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        )
    )
}

หากต้องการอนุญาตให้การดำเนินการลากข้ามขอบเขตของแอป ตัวสร้าง DragAndDropTransferData จะยอมรับอาร์กิวเมนต์ flags ในตัวอย่างต่อไปนี้ ค่าคงที่ DRAG_FLAG_GLOBAL ระบุว่าสามารถลากข้อมูลจากแอปหนึ่งไปยังอีกแอปหนึ่งได้

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        ),
        flags = View.DRAG_FLAG_GLOBAL
    )
}

DragAndDropTransferData ยอมรับแฟล็กที่ระบบ Android View รองรับ ดูรายการค่าคงที่ของ View เพื่อดูรายการ Flag ที่ใช้ได้ทั้งหมด

รับข้อมูลการวาง

กำหนดตัวแก้ไข dragAndDropTarget ให้กับ Composable เพื่อเปิดใช้ Composable ให้รับเหตุการณ์การลากและวาง ตัวแก้ไขมีพารามิเตอร์ 2 รายการ โดยพารามิเตอร์แรกจะทำหน้าที่เป็นตัวกรองและระบุประเภทข้อมูลที่ตัวแก้ไขยอมรับได้ ส่วนพารามิเตอร์ที่ 2 จะส่งข้อมูลใน Callback

โปรดทราบว่าระบบควรจดจำอินสแตนซ์ Callback ข้อมูลโค้ดต่อไปนี้แสดงวิธีจดจำ Callback

val callback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            // Parse received data
            return true
        }
    }
}

หากต้องการรับข้อมูลจากแอปอื่นๆ ให้ใช้ requestDragAndDropPermission เพื่อเปิดใช้การรับ และปล่อยเมื่อเสร็จแล้ว

val externalAppCallback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            val permission =
                activity.requestDragAndDropPermissions(event.toAndroidDragEvent())
            // Parse received data
            permission?.release()
            return true
        }
    }
}

โปรดทราบว่า DragAndDropEvent ที่แสดงผลจาก Callback ของ Compose แตกต่างจากที่เมธอด requestDragAndDropPermission คาดไว้ คุณจึงต้องเรียกใช้ฟังก์ชันส่วนขยาย toAndroidDragEvent() ในพารามิเตอร์ก่อนส่งไปยังคำขอสิทธิ์

ข้อมูลโค้ดถัดไปแสดงวิธีจัดการข้อความธรรมดาที่วางลงในแอป

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

ฟังก์ชัน Callback ควรแสดงผล true หากใช้เหตุการณ์ หรือ false หากปฏิเสธเหตุการณ์และไม่เผยแพร่ไปยังคอมโพเนนต์หลัก

จัดการเหตุการณ์การลากและวาง

ลบล้าง Callback ในอินเทอร์เฟซ DragAndDropTarget เพื่อสังเกตเมื่อเหตุการณ์การลากและวางเริ่มต้น สิ้นสุด หรือเข้าหรือออกจากคอมโพเนนต์เพื่อควบคุม UI และลักษณะการทำงานของแอปอย่างแม่นยำ

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
}

แหล่งข้อมูลเพิ่มเติม

Codelab: ลากและวางใน Compose