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

โดยปกติแล้ว ภาษาที่ใช้แสดงภายในแอปทั้งหมด ควรเก็บไว้ใน String Resource เพื่อให้ตัวแอปสามารถรองรับการแสดงผลได้แต่ละภาษาได้​โดยใช้ประโยชน์จาก Configuration Qualifier บนแอนดรอยด์

ยกตัวอย่างเช่น เจ้าของบล็อกมีแอปของตัวเองที่ต้องการรองรับทั้งหมด 3 ภาษา ก็จะเตรียม Wording ที่ใช้ในแอปไว้ใน String Resource โดยแยกกันแบบนี้

<!-- res/values/strings.xml -->
<resources>
    <string name="common_confirm">Confirm</string>
    <string name="common_cancel">Cancel</string>
    <string name="common_next">Next</string>
</resources>
<!-- res/values-th/strings.xml -->
<resources>
    <string name="common_confirm">ยืนยัน</string>
    <string name="common_cancel">ยกเลิก</string>
    <string name="common_next">ต่อไป</string>
</resources>
<!-- res/values-ko/strings.xml -->
<resources>
    <string name="common_confirm">확인하다</string>
    <string name="common_cancel">취소</string>
    <string name="common_next">다음</string>
</resources>
การกำหนดชื่อใน String Resource ให้ Unique จะช่วยลดโอกาสที่จะ String Resource ตัวอื่นๆ โดน Override ด้วย String Resource ของแอปได้ (เช่น ใน Library ที่นำมาใช้ในแอป)

เวลากำหนด Wording ก็ให้เรียกใช้ค่าจาก String Resource เหล่านี้แทน

<Button
    ...
    android:text="@string/common_next" />
val context: Context = /* ... */
val nextButton: Button = /* ... */

nextButton.text = context.getString(R.string.common_next)
nextButton.setText(R.string.common_next)

และถ้า Wording นั้นๆจำเป็นต้องแสดงพร้อมๆกับตัวแปร ก็สามารถกำหนดรูปแบบของตัวแปรไว้ใน String Resource ได้เลยเช่นกัน

<string name="add_item_order">Add %1$d %2$s in your order.</string>
val context: Context = /* ... */
val amount: Int = /* ... */
val itemName: String = /* ... */
textView.text = context.getString(R.string.add_item_order, amount, itemName)

ไม่รู้ว่าภาษานั้นๆใช้ตัวย่ออะไร?

ในการสร้าง String Resource ถ้าไม่รู้ว่าประเทศนั้นๆจะต้องใช้ตัวอักษรย่ออะไร แนะนำให้สร้างผ่าน GUI ของ Android Studio เพราะจะมี Qualifier ให้เลือก และเมื่อเลือก Qualifier เป็น Locale ก็จะสามารถเลือกประเทศเพื่อสร้าง Value Resource สำหรับภาษานั้นๆได้เลย

โดยการสร้าง Qualifier สำหรับเพื่อให้รองรับหลายๆภาษานั้น จะไม่นิยมสร้าง values-en กัน เพราะว่าภาษาอังกฤษนั้นมักจะเป็น Default Language เสมอ จึงเก็บ Wording สำหรับภาษาอังกฤษไว้ใน values แทน

นอกจากนี้บน Android Studio ยังมี Translations Editor ให้ใช้งานเพื่อช่วยให้นักพัฒนาสามารถแก้ไข Wording ได้ง่ายขึ้นด้วยนะ

ใช้ String Resource แล้วจะเปลี่ยนภาษายังไง?

การกำหนด Wording ผ่าน Configuration Qualifier นี้จะทำให้ภาษาที่แสดงผลนั้นขึ้นอยู่กับ Context ของแอป และแน่นอนว่า Context ของแอปก็จะอิงจากภาษาที่กำหนดไว้ในเครื่องนั่นเอง

แต่บ่อยครั้ง แอปก็จำเป็นต้องเปลี่ยนภาษาที่แสดงแค่ภายในแอปตัวเอง ไม่ได้ต้องการให้แสดงภาษาตามเครื่องเสมอไป ดังนั้นถ้าอยากจะเปลี่ยนภาษาที่จะแสดงผลด้วย String Resource ก็จะต้องเปลี่ยน Locale ที่อยู่ใน Context นั่นเอง

แต่การเปลี่ยน Locale ใน Context นั้นไม่ใช่เรื่องที่ง่ายซักเท่าไร เพราะจะต้องเปลี่ยน Context ทั้งแอป ดังนั้นขอแนะนำให้ใช้ Library ที่ชื่อว่า Localization ดีกว่า (ขายของตัวเอง)

akexorcist/Localization
[Android] In-app language changing library. Contribute to akexorcist/Localization development by creating an account on GitHub.