ลากและวาง

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

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

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

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

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

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

หากต้องการเปิดใช้เหตุการณ์การลากภายในคอมโพเนนต์ ให้เพิ่มตัวแก้ไข dragAndDropSource ซึ่งจะใช้ฟังก์ชันเป็นพารามิเตอร์ ในฟังก์ชันนี้ ให้ใช้ DragAndDropTransferData เพื่อแสดงข้อมูลที่โอนได้ ข้อมูลอาจเป็น URI ระยะไกล ข้อมูลข้อความริชมีเดียในคลิปบอร์ด ไฟล์ในเครื่อง หรืออื่นๆ แต่ต้องรวมข้อมูลทั้งหมดไว้ในออบเจ็กต์ 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 ยอมรับ Flag ที่ระบบ Android View รองรับ ดูรายการค่าคงที่ View เพื่อดูรายการ Flag ที่พร้อมใช้งานทั้งหมด

รับข้อมูลการเปิดตัว

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

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

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 ที่แสดงผลจากการเรียกกลับของ Compose จะแตกต่างจากที่วิธีการ requestDragAndDropPermission คาดไว้ คุณจึงต้องเรียกฟังก์ชันส่วนขยาย toAndroidDragEvent() ในพารามิเตอร์ก่อนที่จะส่งไปยังคำขอสิทธิ์

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

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

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

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

ลบล้างการเรียกกลับในอินเทอร์เฟซ 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: ลากและวางในคอมโพซ