Barrier เป็น Constraint Helper ที่สำคัญตัวหนึ่งสำหรับการใช้งาน Constraint Layout เลยก็ว่าได้ เพื่อช่วยให้นักพัฒนาสามารถจัด UI ที่ซับซ้อนได้ง่ายขึ้น
เพราะ View ที่อยู่ใน ConstraintLayout จะมี View ที่มี Dynamic Size ตาม Content เสมอ ทำให้ View บางตัวไม่สามารถอ้างอิงกับ View ได้แค่ตัวใดตัวหนึ่งเท่านั้น แต่ขึ้นอยู่กับขนาดของ View แต่ละตัวด้วย
ยกตัวอย่างเช่น ต้องการสร้าง UI ที่อยู่ต่อท้าย View 2 ตัว โดยมีเงื่อนไขว่าจะต้องอยู่ต่อท้าย (Bottom) กับ View ตัวที่ใกล้ที่สุด โดยไม่ไปทับกับ View อีกตัวนึง
จากภาพข้างบนจะเห็นว่าถ้า View ฝั่งซ้ายมือใกล้กว่า ก็จะอ้างอิงระยะห่างจาก View ตัวนั้น แต่ถ้า View ฝั่งขวาใกล้กว่า ก็จะอิงจาก View ตัวนั้นแทน
แต่ Constraint ไม่สามารถทำแบบนี้ได้ เพราะอ้างอิงกับ View ได้เพียงแค่ตัวเดียวเท่านั้น จึงต้องใช้ความสามารถของ Barrier เข้ามาช่วย แล้วให้ View ที่ต้องการไปอ้างอิงตำแหน่งจาก Barrier แทน
จากตัวอย่างข้างบนจะได้เป็น XML ออกมาแบบนี้
<androidx.constraintlayout.widget.ConstraintLayout ...>
<TextView
android:id="@+id/textViewLeft"
... />
<TextView
android:id="@+id/textViewRight"
... />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrierHeading"
app:barrierDirection="bottom"
app:constraint_referenced_ids="textViewLeft,textViewRight"
... />
<View
android:id="@+id/viewSeparator"
app:layout_constraintTop_toBottomOf="@id/barrierHeading"
... />
<!-- ... -->
</androidx.constraintlayout.widget.ConstraintLayout>
จะเห็นว่า Barrier มี Attribute เป็นของตัวเองอยู่ 2 ตัวด้วยกันคือ app:barrierDirection
ที่เอาไว้กำหนดว่าจะให้ Barrier อ้างอิงจากด้านไหนของ View และ app:constraint_referenced_ids
สำหรับกำหนดว่าจะให้ Barrier อ้างอิง View ตัวไหนบ้าง
กำหนดทิศทางในการอ้างอิงตำแหน่งให้กับ Barrier
ใช้ Attribute ที่ชื่อว่า app:barrierDirection
ด้วยค่า top
, bottom
, start
และ end
โดยจะมีผลกับ View ทุกตัวที่อ้างอิง ไม่สามารถกำหนดทิศทางแยกกันได้
กำหนด View ที่ต้องการให้ Barrier อ้างอิงตำแหน่ง
ใช้ Attribute ที่ชื่อว่า app:constraint_referenced_ids
สามารถกำหนด View กี่ตัวก็ได้โดยกำหนดเป็น View ID ที่ต้องการได้เลย (ไม่ต้องใส่ @+id
) ถ้ามีหลายตัวก็ให้คั่นระหว่าง View ID แต่ละตัวด้วยเครื่องหมาย ,
การทำงานอื่น ๆ ของ Barrier ที่ควรรู้
Visibility ของ View ที่อ้างอิงใน Barrier มีผลต่อการทำงานของ Barrier
ในกรณีที่ View นั้น ๆ มีค่าเป็น Gone ก็จะทำให้ Barrier อ้างอิงตำแหน่งจาก View ตัวอื่น ๆ ที่เหลืออยู่ และถ้า View ทุกตัวกลายเป็น Gone ก็จะไปอ้างอิงจาก Parent (ConstraintLayout) แทน
แน่นอนว่าการกำหนด Invisible ให้กับ View ก็จะให้ผลลัพธ์ของ Barrier เหมือนกับ Visible นั่นเอง
การกำหนด Margin ให้กับ Barrier จะแตกต่างจาก View ทั่วไป
การใช้ Attribute อย่าง android:layout_margin
จะไม่สามารถใช้กับ Barrier ได้ จะต้องใช้ app:barrierMargin
แทน
Barrier มี Visibility เป็น Gone เสมอ
เป็นเรื่องปกติของ Constraint Helper แทบทุกตัว เพราะใช้เพื่ออ้างอิงตำแหน่งของ View ใน ConstraintLayout เท่านั้น
แต่นั่นก็หมายความว่าถ้ามี View ใด ๆ ก็ตามที่มาอ้างอิงตำแหน่งจาก Barrier และมีการกำหนด Attribute อย่าง android:layout_margin
คู่กับ app:layout_goneMargin
ผลที่ได้ก็คือค่า Margin ของ View ตัวนั้นจะใช้ค่าจาก app:layout_goneMargin
เสมอ เพราะว่า Barrier มี Visibility เป็น Gone นั่นเอง
สรุป
Barrier เป็นหนึ่งใน Constraint Helper ที่สำคัญในการใช้งาน ConstraintLayout เพื่อรองรับ Dynamic UI ในรูปแบบต่าง ๆ ได้สะดวกมากขึ้น จึงทำให้การใช้งาน ConstraintLayout จะต้องมีการหยิบ Barrier เข้ามาช่วยอยู่บ่อย ๆ และในขณะเดียวกัน Barrier ก็มีรูปแบบการทำงานของตัวเองอยู่ ทำให้ในบางครั้งกลายเป็นข้อจำกัดในการสร้าง UI บางรูปแบบ อาจจะต้องมีการปรับรูปแบบของ View ต่าง ๆ ใน ConstraintLayout นิดหน่อยเพื่อให้สอดคล้องกับการทำงานของ Barrier