26 November 2016

เลิกใช้ Left/Right และเปลี่ยนมาใช้ Start/End ใน Layout ของแอนดรอยด์แทนได้แล้วนะ

Created on Saturday, November 26, 2016

การสร้าง Layout ของแอนดรอยด์จะขาด Margin, Padding หรือ Gravity ไปไม่ได้อย่างแน่นอน และนักพัฒนาก็จะคุ้นเคยกันดีกับการอ้างอิงตำแหน่งในรูปแบบของ Top, Bottom, Left และ Right แต่หารู้ไม่ว่าในปัจจุบันนี้แอนดรอยด์ได้เปลี่ยนมาใช้เป็น Top, Bottom, Start และ End แทนแล้วนะ

การอ้างอิงทิศทางแบบเดิมๆ

ผู้ที่หลงเข้ามาอ่านส่วนใหญ่คงจะคุ้นเคยกับการอ้างอิงทิศทางรอบๆ View กันอยู่แล้ว ซึ่งจะเป็นแบบนี้


และเวลากำหนดค่าอย่าง Margin หรือ Padding แค่ด้านใดด้านหนึ่งของ View ก็จะต้องกำหนด Attribute กับให้ View ในลักษณะแบบนี้

android:layout_marginRight="20dp"
android:paddingLeft="10dp"

อาจจะฟังดูเหมือนปกติ แต่ว่าจริงๆแล้วการใช้ Attribute โดยใช้ Left หรือ Right นั้นยังไม่ใช่วิธีที่ดีซักเท่าไร

เพราะไม่ใช่ทุกภาษาบนโลกที่อ่านจากซ้ายไปขวา

เมื่อมีแอนดรอยด์เวอร์ชันใหม่เปิดตัวขึ้นมา สิ่งหนึ่งที่ถูกเพิ่มเข้ามาเรื่อยๆก็คือการรองรับภาษาให้มากขึ้น หรือการปรับปรุงการแสดงผลของภาษาให้ครอบคลุมและดียิ่งขึ้น ดังนั้นแอนดรอยด์ในปัจจุบันนี้จึงรองรับการแสดงผลแบบ RTL (Right to Left) จากเดิมที่เป็น LTR (Left to Right) มาตลอด ทั้งนี้ก็เพราะว่ายังมีหลายภาษาที่ใช้วิธีการอ่านจากขวาไปซ้าย (เช่น ภาษาเปอร์เซียน)


แอนดรอยด์นั้นเริ่มรองรับการแสดงผลแบบ RTL ใน Android 4.1 Jelly Bean (API 16) แต่ยังไม่สมบูรณ์มากนัก ต่อมาใน Android 4.2 Jelly Bean (API 17) จึงสามารถรองรับการแสดงผลแบบ RTL ได้อย่างสมบูรณ์แบบ

ลองทดสอบการแสดงผลแบบ RTL

ผู้ที่หลงเข้ามาอ่านสามารถทดสอบว่าแอปฯรองรับกับ RTL ได้สมบูรณ์หรือไม่ ด้วยการเข้าไปที่ SettingsDeveloper Options > Force RTL Layout Direction


เมื่อลองเทียบการแสดงผลระหว่าง LTR กับ RTL ก็จะได้ออกมาเป็นแบบนี้


จะเห็นว่าทุกอย่างดูคล้ายเป็นการแสดงผลแบบ Mirror แต่ก็ไม่ได้ Mirror แบบ 100% เพราะข้อความต่างๆที่แสดงผลก็ยังอ่านจากซ้ายไปขวา โดย View ต่างๆจะถูกจัดชิดขวาแทน และลำดับการจัดของ Layout ต่างๆจะเปลี่ยนจากชิดซ้ายให้กลายเป็นชิดขวาแทน

ไม่ควรใช้ Left และ Right เมื่อแสดงผลแบบ RTL

อย่างที่บอกไปว่ามันไม่ใช่การแสดงผลแบบ Mirror แค่การจัด Layout จะถูกย้ายจุดอ้างอิงจากซ้ายมือของหน้าจอไปเป็นขวามือแทน และปัญหาที่จะเกิดขึ้นก็คือ เวลาที่กำหนดค่าใน Layout ด้วย Left และ Right ไว้ เช่นตัวอย่างนี้


Image View ที่กำหนด android:layout_marginRight ไว้ เมื่อแสดงผลเป็น RTL จะทำให้การแสดงของ Layout ไม่ถูกต้อง เพราะว่า Image View ตัวนั้นยังคงมี Margin เป็น Right อยู่

ดังนั้นทีมพัฒนาแอนดรอยด์จึงเพิ่ม Start/End เพื่อให้นักพัฒนาใช้งานแทน Left/Right เพื่อรองรับการแสดงผลแบบ RTL




จะเห็นว่าการแสดงผลแบบ LTR กับ RTL จะมีความแตกต่างกันตรงที่ Start กับ End นั้นสลับฝั่งกัน ในขณะที่การใช้ Left กับ Right จะไม่สามารถทำแบบนี้ได้ (เพราะการสลับตำแหน่ง Left กับ Right จะทำให้เกิดความสับสนได้)

สำหรับแอปที่รองรับแอนดรอยด์เวอร์ชันต่ำกว่า API 17 

เนื่องจาก Start/End ถูกเพิ่มเข้ามาใน Android 4.2 Jelly Bean (API 17) ดังนั้นถ้าแอปรองรับกับแอนดรอยด์เวอร์ชันที่ต่ำกว่านั้นและอยากจะให้รองรับ RTL ถ้าแสดงผลบนแอนดรอยด์เวอร์ชันใหม่ๆด้วย ก็ให้ใช้ Attribute ทั้ง Left/Right และ Start/End ทั้งคู่ได้เลย

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="16dp"
    android:layout_marginStart="16dp"
    android:text="Hello World"/>

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginEnd="10dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="10dp"
    android:layout_marginStart="16dp"
    android:text="OK"/>

โดย Start จะใช้คู่กับ Left และ End จะใช้คู่กับ Right

แต่ถ้าแอปรองรับกับแอนดรอยด์เวอร์ชันสูงกว่า API 17 ก็ไม่ต้องสนใจเรื่องนี้และเปลี่ยนไปใช้ Start และ End ทั้งหมดได้เลย

Configuration Qualifier สำหรับ Layout Direction 

ในกรณีที่อยากจะทำ Configuration Qualifier เพื่อรองรับ RTL จะใช้คำว่า ldrlt (Layout direction right-to-left) และถ้าเป็น LTR ก็จะใช้คำว่า ldltr (Layout direction left-to-right)


แต่ในการใช้งานจริงให้แยกสำหรับ RTL ก็พอแล้ว เพราะการแสดงแบบ LTR สามารถใช้ Default Resource ได้เลย

สรุป

ถึงแม้ว่าการทำให้รองรับการแสดงผลแบบ RTL อาจจะดูไม่สำคัญนักในสายตาของนักพัฒนาส่วนใหญ่ แต่เมื่อแอปฯที่เติบโตจนต้อง Scale เข้าสู่ระดับ Global การทำ App Localization จะเป็นสิ่งที่สำคัญมาก ดังนั้นเพื่อให้ครอบคลุมกับกลุ่มผู้ใช้งานทั่วโลกก็จะไม่พ้นการทำแอปฯให้รองรับกับ RTL นั่นเอง

ถ้าคิดว่าไม่น่าจะได้ Scale ไปในระดับนั้น และกลุ่มผู้ใช้ก็ไม่จำเป็นต้องทำ RTL ก็มองข้ามไปได้เลย แต่อย่างน้อยเวลาออกแบบ Layout XML ก็แนะนำให้หัดใช้ Start/End ด้วยดีกว่านะครับ วันหลังเกิดเหตุจำเป็นขึ้นมาก็จะได้ไม่ต้องลำบาก