หัวข้อสำคัญ

ส่วนต่อไปนี้จะอธิบายแนวคิดหลักบางประการสำหรับกระบวนการลากและวาง

ขั้นตอนการลากและวาง

กระบวนการลากและวางจะมีอยู่ 4 ขั้นตอนหรือสถานะ 4 ขั้นตอน ได้แก่ เริ่มแล้ว ดำเนินการต่อ ทิ้ง และสิ้นสุด

เริ่มต้นแล้ว

แอปพลิเคชันของคุณเรียกแอปพลิเคชันเพื่อตอบสนองต่อท่าทางสัมผัสการลากของผู้ใช้ startDragAndDrop() เพื่อบอกให้ระบบเริ่มการดำเนินการลากและวาง อาร์กิวเมนต์ของเมธอดจะมีข้อมูลต่อไปนี้

  • ข้อมูลที่จะลาก
  • Callback สำหรับการวาดเงาการลาก
  • ข้อมูลเมตาที่อธิบายเกี่ยวกับข้อมูลที่ลาก
  • ระบบจะตอบสนองด้วยการกลับไปที่แอปพลิเคชันของคุณเพื่อเพิ่มการลาก เงา จากนั้นระบบจะแสดงเงาการลากบนอุปกรณ์
  • ถัดไป ระบบจะส่งเหตุการณ์การลากที่มีประเภทการดำเนินการ ACTION_DRAG_STARTED ไปยังเหตุการณ์การลาก Listener ของออบเจ็กต์ View ทั้งหมดในเลย์เอาต์ปัจจุบัน ถึง ยังคงได้รับเหตุการณ์การลากต่อไป ซึ่งรวมถึงการลดลงที่อาจเกิดขึ้น เหตุการณ์ - Listener เหตุการณ์การลากต้องแสดงผล true การดำเนินการนี้จะลงทะเบียน ผู้ฟังด้วยระบบ เฉพาะ Listener ที่ลงทะเบียนเท่านั้นไปยัง รับเหตุการณ์การลาก ณ จุดนี้ ผู้ฟังยังสามารถเปลี่ยน ปรากฏของออบเจ็กต์ View เป้าหมายการลดลงเพื่อแสดงว่ามุมมองสามารถ ยอมรับเหตุการณ์การเปิดตัว
  • หาก Listener เหตุการณ์การลากแสดงผล false ก็จะไม่ได้รับคำสั่งลาก เหตุการณ์สำหรับการดำเนินการปัจจุบันจนกว่าระบบจะส่งเหตุการณ์การลาก ที่มีประเภทการดำเนินการ ACTION_DRAG_ENDED การส่งคืน false หมายความว่าผู้ฟังบอกระบบว่าไม่สนใจ ในการดำเนินการลากและวาง และไม่ต้องการยอมรับข้อมูลที่ลากมา
ต่อไป
ผู้ใช้ลากต่อไปเรื่อยๆ ขณะที่เงาการลากมาตัดกับ กรอบล้อมรอบของเป้าหมายแบบเลื่อนลง ระบบจะส่งเหตุการณ์การลากอย่างน้อย 1 รายการไปยัง Listener เหตุการณ์การลากของเป้าหมาย ผู้ฟังอาจเปลี่ยนรูปลักษณ์ เป้าหมายการลดลง View เพื่อตอบสนองต่อเหตุการณ์ เช่น หากเหตุการณ์ ระบุว่าเงาการลากเข้ามาในกรอบของเส้นแบ่งที่วาง เป้าหมาย - ประเภทการดำเนินการ ACTION_DRAG_ENTERED — ผู้ฟังจะโต้ตอบได้ด้วยการไฮไลต์ View
ยกเลิก
ผู้ใช้ปล่อยเงาการลากภายในช่องที่ล้อมรอบของเส้นตก เป้าหมาย ระบบจะส่งเหตุการณ์การลากที่มีการกระทำแก่ Listener ของเป้าหมายแบบเลื่อนลง ประเภท ACTION_DROP ออบเจ็กต์เหตุการณ์การลากมีข้อมูลที่ส่งไปยังระบบใน โทรหา startDragAndDrop() ที่เริ่มการดำเนินการ ผู้ฟังคือ คาดว่าจะแสดงผลบูลีน true ในระบบหาก Listener สำเร็จ ประมวลผลข้อมูลที่ลบออก : ขั้นตอนนี้จะเกิดขึ้นหากผู้ใช้วางเงาการลากภายใน กรอบล้อมรอบของ View ที่ลงทะเบียน Listener ไว้เพื่อรับเหตุการณ์การลากแล้ว (เป้าหมายแบบเลื่อนลง) หากผู้ใช้ปล่อยเงาการลากในส่วนอื่นๆ จะไม่มีการส่ง ACTION_DROP เหตุการณ์การลาก
สิ้นสุดแล้ว

หลังจากผู้ใช้ปล่อยเงาการลาก และหลังจากที่ระบบส่งข้อความ

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

แต่ละขั้นตอนดังกล่าวมีการอธิบายรายละเอียดเพิ่มเติมในส่วนที่ชื่อ การดำเนินการลากและวาง

เหตุการณ์การลาก

ระบบจะส่งเหตุการณ์การลากในรูปแบบของออบเจ็กต์ DragEvent มีประเภทการดำเนินการที่อธิบายสิ่งที่เกิดขึ้นในการลากและวาง ขั้นตอนได้ ออบเจ็กต์ยังมีข้อมูลอื่นๆ ได้ด้วย ทั้งนี้ขึ้นอยู่กับประเภทการทํางาน

Listener เหตุการณ์การลากจะได้รับออบเจ็กต์ DragEvent ดูประเภทการดำเนินการ Listener การโทร DragEvent.getAction() มีค่าที่เป็นไปได้ 6 ค่าที่กำหนดโดยค่าคงที่ในคลาส DragEvent ซึ่งอธิบายในตาราง 1:

ตาราง 1 ประเภทการทำงานของ DragEvent

ประเภทการดำเนินการ ความหมาย
ACTION_DRAG_STARTED แอปพลิเคชันเรียก startDragAndDrop() และรับ และเงาการลาก หากผู้ฟังต้องการรับเหตุการณ์การลากต่อไป สำหรับการดำเนินการนี้ ค่าจะต้องคืนค่าบูลีน true ไปยังฟังก์ชัน ระบบ
ACTION_DRAG_ENTERED เงาการลากจะเข้าสู่กรอบของ Listener เหตุการณ์การลาก View นี่เป็นการดำเนินการประเภทแรกที่ Listener ดำเนินการ ได้รับเมื่อเงาการลากเข้าสู่กรอบ
ACTION_DRAG_LOCATION ต่อจาก ACTION_DRAG_ENTERED เหตุการณ์ เงาการลากยังอยู่ ภายในช่องที่ล้อมรอบของ Listener เหตุการณ์การลาก View
ACTION_DRAG_EXITED กำลังติดตาม ACTION_DRAG_ENTERED และอย่างน้อย 1 คน ACTION_DRAG_LOCATION เหตุการณ์ เงาการลากเคลื่อน นอกกรอบของ Listener เหตุการณ์การลาก View
ACTION_DROP เงาการลากจะปล่อยเหนือ Listener เหตุการณ์การลาก View มีการส่งการดำเนินการนี้ไปที่ View Listener ของออบเจ็กต์เฉพาะเมื่อ Listener แสดงผลเป็นบูลีน true เพื่อตอบสนองต่อ เหตุการณ์การลาก ACTION_DRAG_STARTED รายการ การดำเนินการประเภทนี้ไม่ใช่ ส่งหากผู้ใช้ปล่อยเงาการลากเหนือ View ผู้ฟังที่ไม่ได้ลงทะเบียนหรือผู้ใช้ปล่อยการลาก เงาเหนือสิ่งใดก็ตามที่ไม่ได้เป็นส่วนหนึ่งของเลย์เอาต์ปัจจุบัน

Listener จะแสดงผลบูลีน true หาก ประมวลผลการลดลงเรียบร้อยแล้ว ไม่เช่นนั้นจะต้องส่งคืน false

ACTION_DRAG_ENDED ระบบจะสิ้นสุดการดำเนินการลากและวาง การดำเนินการประเภทนี้ ไม่จำเป็นต้องอยู่ข้างหน้าด้วยเหตุการณ์ ACTION_DROP ถ้า ระบบจะส่ง ACTION_DROP โดยรับ ประเภทการดำเนินการ ACTION_DRAG_ENDED ไม่ได้บอกเป็นนัยว่า ประสบความสำเร็จ ผู้ฟังต้องเรียก getResult(), ตามที่แสดงในตาราง 2 เพื่อหาค่าที่ ตอบกลับ ACTION_DROP แล้ว หากมี ไม่ได้ส่ง ACTION_DROP เหตุการณ์ getResult() แสดงผล false

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

ตาราง 2 ข้อมูล DragEvent ที่ถูกต้องตามประเภทการดำเนินการ

ค่า getAction()
ค่า getClipDescription()
ค่า getLocalState()
ค่า getX()
ค่า getY()
ค่า getClipData()
ค่า getResult()
ACTION_DRAG_STARTED &ตรวจสอบ; &ตรวจสอบ;        
ACTION_DRAG_ENTERED &ตรวจสอบ; &ตรวจสอบ;        
ACTION_DRAG_LOCATION &ตรวจสอบ; &ตรวจสอบ; &ตรวจสอบ; &ตรวจสอบ;    
ACTION_DRAG_EXITED &ตรวจสอบ; &ตรวจสอบ;        
ACTION_DROP &ตรวจสอบ; &ตรวจสอบ; &ตรวจสอบ; &ตรวจสอบ; &ตรวจสอบ;  
ACTION_DRAG_ENDED   &ตรวจสอบ;       &ตรวจสอบ;

เมธอด DragEvent getAction() describeContents() writeToParcel() และ toString() เสมอ แสดงผลข้อมูลที่ถูกต้อง

ถ้าเมธอดไม่มีข้อมูลที่ถูกต้องสำหรับการดำเนินการประเภทหนึ่งๆ ระบบจะแสดงผลค่า null หรือ 0 ขึ้นอยู่กับประเภทผลการค้นหา

เงาการลาก

ในระหว่างการดำเนินการลากและวาง ระบบจะแสดงรูปภาพที่ผู้ใช้ การลาก สำหรับการเคลื่อนไหวของข้อมูล รูปภาพนี้จะแสดงข้อมูลที่ถูกลาก สำหรับ การดำเนินการอื่นๆ รูปภาพจะแสดงบางส่วนของการดำเนินการลาก

ภาพดังกล่าวเรียกว่าเงาลาก คุณสร้างโดยใช้วิธีการที่คุณประกาศให้ CANNOT TRANSLATE View.DragShadowBuilder ออบเจ็กต์ คุณต้องส่งเครื่องมือสร้างไปยังระบบเมื่อคุณเริ่มการลากและวาง การดำเนินการโดยใช้ startDragAndDrop() เป็นส่วนหนึ่งของการตอบสนองต่อ startDragAndDrop() ระบบจะเรียกใช้เมธอด Callback ที่คุณกำหนดใน View.DragShadowBuilder เพื่อให้ได้เงาการลาก

คลาส View.DragShadowBuilder มีตัวสร้าง 2 รายการ:

View.DragShadowBuilder(View)

เครื่องมือสร้างนี้ยอมรับ View ออบเจ็กต์ ร้านเครื่องมือก่อสร้าง ออบเจ็กต์ View ในออบเจ็กต์ View.DragShadowBuilder ดังนั้น Callback สามารถเข้าถึงโมเดลเพื่อสร้างเงาการลากได้ มุมมองไม่จำเป็นต้องเป็น View ที่ผู้ใช้เลือกเพื่อเริ่มการดำเนินการลาก

หากใช้ตัวสร้างนี้ คุณก็ไม่ต้องขยาย View.DragShadowBuilder หรือลบล้างเมธอดของ URL โดยค่าเริ่มต้น คุณจะได้ลาก เงาที่ปรากฏเหมือนกับ View ที่คุณส่งเป็นอาร์กิวเมนต์ ตรงตำแหน่งที่ผู้ใช้แตะหน้าจอ

View.DragShadowBuilder()

หากคุณใช้ตัวสร้างนี้ จะไม่มีออบเจ็กต์ View อยู่ใน View.DragShadowBuilder ออบเจ็กต์ ตั้งค่าช่องนี้เป็น null คุณต้องขยายเวลา View.DragShadowBuilder และลบล้างเมธอดของ URL นี้ มิเช่นนั้นคุณจะได้รับ เงาการลากที่มองไม่เห็น โดยไม่แสดงข้อผิดพลาด

คลาส View.DragShadowBuilder มี 2 วิธีที่ช่วยสร้างการลากร่วมกัน เงา:

onProvideShadowMetrics()

ระบบจะเรียกใช้เมธอดนี้ทันทีหลังจากที่คุณเรียก startDragAndDrop() ใช้วิธีการส่งขนาดและจุดสัมผัสของเงาการลากไปยัง ระบบ เมธอดมีพารามิเตอร์ 2 ตัว ได้แก่

outShadowSize:Point ออบเจ็กต์ ความกว้างของเงาการลากจะอยู่ใน x และความสูงของพื้นที่ y

outShadowTouchPoint: ออบเจ็กต์ Point ทัชพอยต์คือตําแหน่ง ภายในเงาการลากที่ต้องอยู่ใต้นิ้วของผู้ใช้ในระหว่างการลาก ตำแหน่ง X ไปใน x และตำแหน่ง Y ไปใน y

onDrawShadow()

ทันทีหลังจากที่โทรหา onProvideShadowMetrics() ระบบโทร onDrawShadow() เพื่อสร้างเงาการลาก เมธอดมีเพียงรายการเดียว ซึ่งเป็นออบเจ็กต์ Canvas ที่ ที่ระบบสร้างจากพารามิเตอร์ที่คุณให้ไว้ใน onProvideShadowMetrics() วิธีวาดเงาการลากบนภาพที่ให้ไว้ Canvas

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

ลาก Listener เหตุการณ์และวิธีการเรียกกลับ

View ได้รับเหตุการณ์การลากที่มี Listener เหตุการณ์การลากซึ่งนำไปใช้งาน View.OnDragListener หรือด้วยเมธอด Callback onDragEvent() ของมุมมอง วันและเวลา ระบบจะเรียกเมธอดหรือผู้ฟัง ซึ่งจะให้ DragEvent

ในกรณีส่วนใหญ่ การใช้ Listener จะดีกว่าการใช้เมธอด Callback วันและเวลา ที่คุณออกแบบ UI ซึ่งมักไม่ใช่คลาส View ย่อย แต่การใช้คลาส เมธอด Callback จะบังคับให้คุณสร้างคลาสย่อยเพื่อลบล้างเมธอด ใน คุณสามารถใช้คลาส Listener 1 รายการ แล้วใช้กับคลาส ออบเจ็กต์ View ที่ต่างกัน คุณยังติดตั้งใช้งานเป็นคลาสในบรรทัดแบบไม่ระบุตัวตนได้ด้วย หรือสีหน้าแลมบ์ดา หากต้องการตั้งค่า Listener สำหรับออบเจ็กต์ View ให้เรียก setOnDragListener()

นอกจากนี้ คุณยังสามารถปรับเปลี่ยนการใช้งานเริ่มต้นของ onDragEvent() โดยไม่ลบล้างเมธอด ตั้งค่า OnReceiveContentListener ในมุมมอง ดูรายละเอียดเพิ่มเติมได้ที่ setOnReceiveContentListener() จากนั้นเมธอด onDragEvent() จะดำเนินการต่อไปนี้โดยค่าเริ่มต้น

  • แสดงค่า "จริง" เพื่อตอบสนองต่อการเรียก startDragAndDrop()
  • การโทร performReceiveContent() หากข้อมูลลากและวางหายไปในมุมมอง ส่งข้อมูลไปยัง เป็นออบเจ็กต์ ContentInfo จะเรียกใช้ OnReceiveContentListener

  • แสดงค่า "จริง" หากข้อมูลการลากและวางหายไปในมุมมองและ OnReceiveContentListener จะใช้เนื้อหาใดก็ได้

กําหนด OnReceiveContentListener เพื่อจัดการข้อมูลสําหรับ แอป สำหรับความเข้ากันได้แบบย้อนหลังไปจนถึง API ระดับ 24 ให้ใช้เวอร์ชัน Jetpack OnReceiveContentListener

คุณสามารถมี Listener เหตุการณ์แบบลากและเมธอด Callback สำหรับออบเจ็กต์ View ได้ใน ในกรณีนี้ระบบจะเรียกผู้ฟังก่อน ระบบจะไม่เรียกการเรียกฟังก์ชัน เมธอด Callback เว้นแต่ Listener จะแสดง false

ชุดค่าผสมของเมธอด onDragEvent() และ View.OnDragListener คือ คล้ายกับการผสมระหว่าง onTouchEvent() และ View.OnTouchListener ที่ใช้กับกิจกรรมการสัมผัส