26 พฤศจิกายน 2559

[Android Design] เรื่องราวของ Left/Right กับ Start/End ของ Layout ในแอนดรอยด์



        โดยปกติแล้วเวลาจัด Layout XML ในแอนดรอยด์อย่างเช่นค่า Padding, Margin หรือ Align ต่างๆของ Relative Layout นั้นจะสามารถกำหนดทิศทางที่ต้องการได้คือ Top, Bottom, Left และ Right

        แต่รู้หรือไม่ว่าแอนดรอยด์ในทุกวันนี้ได้เปลี่ยนมาใช้เป็น Top, Bottom, Start และ End แล้วนะ เพราะอะไรกันนะ?

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

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


        สมมติว่ากำหนด Margin หรือ Padding ก็จะออกมาเป็น XML ในลักษณะแบบนี้

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

     

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

        เมื่อมีแอนดรอยด์เวอร์ชันใหม่เปิดตัวขึ้นมา สิ่งหนึ่งที่ถูกเพิ่มเข้ามาเรื่อยๆก็คือการรองรับภาษาให้มากขึ้น หรือการปรับปรุงการแสดงผลของภาษาให้ครอบคลุมและดียิ่งขึ้น ดังนั้นแอนดรอยด์ในปัจจุบันนี้จึงรองรับการแสดงผลแบบ 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 ได้สมบูรณ์หรือไม่ ด้วยการเข้าไปที่ Developer Options > Force RTL Layout Direction


        เมื่อเทียบความแตกต่างระหว่าง LTR กับ RTL จะต่างกันแบบนี้


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

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

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

        ดังนั้น Left และ Right ก็คงเหมือนเดิมไม่ว่าจะเป็น LTR หรือ RTL ครับ

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


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

        ดังนั้นทีมพัฒนาแอนดรอยด์จึงกำหนดคำว่า Start/End เพื่อใช้งานแทน Left/Right เพื่อให้เข้าใจได้ง่ายกว่านั่นเอง


        จะเห็นว่าการแสดงผลแบบ LTR กับ RTL จะมีความแตกต่างกันตรงที่ Start กับ End นั้นสลับฝั่งกัน เพื่อแก้ปัญหาดังกล่าวที่เกิดขึ้นเมื่อใช้ Left กับ Right

สิ่งที่ควรรู้

        Start/End นั้นรองรับกับ Android 4.2 Jelly Bean (API 17) ขึ้นไป ถ้าแอปฯของผู้ที่หลงเข้ามาอ่านรองรับกับเวอร์ชันต่ำกว่านั้น แต่อยากจะรองรับ RTL ในเวอร์ชันใหม่ด้วย ให้ประกาศ XML 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 สำหรับ 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 ด้วยดีกว่านะครับ วันหลังเกิดเหตุจำเป็นขึ้นมาก็จะได้ไม่ต้องลำบาก




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium