web analytics

Flutter : การทำลาก-วาง (Draggable) ใน Flutter

cover

สวัสดีทุกท่าน ช่วงนี้ผมมีโปรเจคคิดว่าจะทำเล่นๆไปเรื่อยๆ แล้วมีโปรเจคนึงคิดว่าต้องใช้การลาก วาง widget ในแแอป วันนี้ก็เลยลองเล่นเกี่ยวกับ การทำ ลาก-วาง (draggable) บน Flutter ครับ เลยมาเขียนสรุปคร่าวๆในบล็อกนี้

 

เริ่มต้น

เตรียมตัวให้พร้อม
new Flutter Project

1

 

Draggable Widget

Draggable เป็น Widget ที่เมื่อนำมาครอบ Widget อื่น Widget นั้นก็จะลากได้ ง่ายๆแค่นี้แหละ
โดยมี ลูกเล่นหลักๆ 3 อันคือ

child = View ลูกที่แสดงตอนยังไม่ได้ถูกลาก
feedback = View ที่แสดง ขณะกำลังถูกลากไปพร้อมกับเรา
vhildWhenDragging = View ลูกที่แสดงขณะกำลังถูกลากอยู่

 

เพื่อความเข้าใจ ผมลองสร้าง Container แล้วลองเพิ่ม Draggable ให้มัน

a1

 

ดังนั้นถ้าอยากให้มันเหมือนกำลังถูกลากไปจริงๆ ก็ไม่ต้องใส่ childWhenDragging

2

 

โดยเราสามารถกำหนดให้ลากได้เฉพาะแนวตั้งหรือแนวนอนก็ได้
โดยใช้ axis

a3

 

อีกอันที่น่าจะมีประโยชน์คือ dragAnchor มันก็คือการระบุว่าจะให้แสดง feedback ตรงไหน
โดยปกติจะมีค่าเป็น DragAnchor.child แต่ถ้าเรากำหนดแบบ pointer มันจะแสดง feedback ตรงตำแหน่งที่เรากดแทน

a10

 

Draggable listener

ลูกเล่นเพิ่มเติม คือ Listener ของ Draggable ซึ่งสามารถทำได้หลายอย่าง เช่น

onDragStarted = ถูกเรียกเมื่อเราเริ่มลาก
onDragCompleted = ถูกเรียกเมื่อเราลากแล้ว Target ยอมรับ เดี๋ยวจะพูดถึงในหัวข้อถัดไป
onDragEnd = ถูกเรียกเมื่อ เราวางแล้ว ไม่ว่าจะ Target ยอมรับหรือไม่
onDraggableCanceled = ถูกเรียกเมื่อ ลากไปวางในที่ๆ Target ไม่มี หรือไม่ถูกยอมรับ

 

ลองดู Cycle คร่าวๆ

a7

 

โดยตัว onDragEnd จะมี details ส่งมาให้ด้วย ซึ่งก็เช็คได้หลายอย่าง เช่น Target ยอมรับหรือไม่
ระยะทาง ตำแหน่งที่วางสุดท้าย

 

หลายคน ถ้าใหม่ๆอาจจะสงสัยว่า เราจะรู้ได้อย่างไรว่า callback ที่มันส่งกลับมามี argument อะไรบ้าง
วิธีการก็คือ กดเข้าไปดู Definition ของมัน (Ctrl+คลิก) เช่น onDragEnd ก็กดเข้าไปดูว่ามันเป็น Function แบบไหน

a9

 

 

 

Draggable Data

อย่างที่เรารู้กันว่า การที่เราลาก object ก็เพราะเราต้องการทำอะไรบ้างอย่าง ดังนั้นมันก็ต้องมีจุดหมายของการลาก และการที่จุดหมายนั้นจะรู้ว่าเราลากอะไรไปวาง มันก็ต้องมีข้อมูลติดไปด้วย

draggable สามารถกำหนดข้อมูลไปกับมันได้ โดยใช้ data

 

Drag Target

พอทำให้ widget ลากได้แล้ว ก็ต้องมีจุดหมายที่รออยู่ (Target)
โดยตัวอย่างนี้ผมจะทำ widget สองตัว โดยลากตัวนึงแล้วจะ +1 แสดงผลที่ widget อีกตัว

 

เตรียม Draggable กำหนด data เป็น 1

 

ต่อมาก็ทำ DragTarget โดยตัวละครสำคัญของมันคือ

builder = Widget ที่แสดง
candidateData = ข้อมูลที่ถูกยอมรับเข้ามา
rejectdData = ข้อมูลที่ไม่ยอมรับ
onWillAccept = ตรวจสอบว่า ข้อมูลที่รับมาจาก Draggable ตรงกับที่ต้องการหรือไม่
onAccept = ยอมรับ แล้วทำอะไร

 

สิ่งที่ผมจะทำก็คือ builder ก็ return Widget แสดง count
onWillAccept ก็เช็คว่า ข้อมูลตรงมัย ในที่นี้คือ ต้องมีค่า = 1
onAcept เมื่อยอมรับแล้วก็ + ค่าให้กับ count

 

ลองรัน

a4

 

ที่เหลือ listener ของ DragTarget อีกอันคือ

onLeave = เมื่อลาก widget ออกจาก Target

 

ลองดู cycle ของ DragTarget

a5

 

ทีนี้ลองทำ Draggble เพิ่มอีกตัว คือ data มีค่า -1

a6

 

สุดท้ายลองมาดู ภาพรวม cycle ของ Draggable + DragTarget ครับ

a8

 

จบแล้ว

บล็อกนี้เป็นพื้นฐานการทำ Draggable ใน Flutter ครับ จะเห็นว่าทำ draggable ทำได้ง่ายมาก หวังว่าบล็อกนี้จะมีประโชน์ครับ (:

 

โค้ดทั้งหมดอยู่ที่ Gist Github
https://gist.github.com/benznest/a784012f046efed6ee214481f0fb7def

 

Credit
https://medium.com/flutter-community/a-deep-dive-into-draggable-and-dragtarget-in-flutter-487919f6f1e4