แอปมีแหล่งข้อมูลที่เฉพาะเจาะจงกับวัฒนธรรมหนึ่งๆ ตัวอย่างเช่น แอปสามารถรวมสตริงเฉพาะวัฒนธรรมที่แปลเป็นภาษา ภาษาของพื้นที่ปัจจุบัน
วิธีที่ดีคือให้ ทรัพยากรเฉพาะวัฒนธรรมที่แยกจากส่วนอื่นๆ ของแอป Android แก้ปัญหา แหล่งข้อมูลเฉพาะภาษาและวัฒนธรรมตามการตั้งค่าภาษาของระบบ คุณ สามารถให้การสนับสนุนสำหรับภาษาต่างๆ โดยใช้ไดเรกทอรีทรัพยากรใน โปรเจ็กต์ Android ของคุณ
คุณสามารถระบุแหล่งข้อมูลที่ปรับแต่งให้เหมาะกับวัฒนธรรมของผู้คนที่ใช้
แอป คุณจะระบุประเภททรัพยากรใดก็ได้ที่
ที่เหมาะสมกับภาษาและวัฒนธรรมของผู้ใช้ ตัวอย่างเช่น พารามิเตอร์
ภาพหน้าจอต่อไปนี้แสดงแอปที่แสดงสตริงและทรัพยากรที่ถอนออกได้ใน
ภาษาen_US
เริ่มต้นของอุปกรณ์และภาษาสเปน
ภาษาes_ES
![แอปแสดง
ข้อความและไอคอนแตกต่างกันไปตามภาษาปัจจุบัน](https://developer.android.com/static/images/training/languages_01.png?authuser=9&hl=th)
รูปที่ 1 แอปที่ใช้ทรัพยากรต่างกันขึ้นอยู่กับ สถานที่ปัจจุบัน
เมื่อสร้างโปรเจ็กต์โดยใช้ Android SDK
เครื่องมือ เครื่องมือจะสร้างไดเรกทอรี res/
ในระดับบนสุดของ
ให้กับโครงการ ภายในไดเรกทอรี res/
นี้คือไดเรกทอรีย่อยสำหรับทรัพยากรต่างๆ
ประเภทต่างๆ นอกจากนี้ยังมีไฟล์เริ่มต้นอีก 2-3 ไฟล์ เช่น res/values/strings.xml
ซึ่งมีค่าสตริงของคุณ
การรองรับภาษาต่างๆ นอกเหนือจากการใช้ทรัพยากรเฉพาะภาษาแล้ว ผู้ใช้บางรายเลือกภาษาที่ใช้สคริปต์แบบขวาไปซ้าย (RTL) เช่น อาหรับหรือฮีบรูสำหรับภาษา UI ผู้ใช้รายอื่นๆ ที่ตั้งค่าภาษาใน UI เป็นภาษาที่ใช้ สคริปต์ LTR เช่น ภาษาอังกฤษ อาจดูหรือสร้างเนื้อหา ในภาษาที่ใช้สคริปต์ RTL เพื่อรองรับผู้ใช้ทั้ง 2 ประเภท แอปของคุณจำเป็นต้องทำสิ่งต่อไปนี้
- ใช้การจัดวาง UI RTL สำหรับภาษา RTL
- ตรวจหาและประกาศทิศทางของข้อมูลข้อความที่แสดงภายใน ข้อความที่จัดรูปแบบ โดยทั่วไปแล้ว คุณจะ เรียกเมธอดตามที่อธิบายไว้ใน คู่มือนี้จะอธิบายถึง ทิศทางของข้อมูลข้อความให้กับคุณ
สร้างไดเรกทอรีภาษาและไฟล์ทรัพยากร
หากต้องการเพิ่มการรองรับภาษาเพิ่มเติม ให้สร้างไดเรกทอรีเพิ่มเติมภายใน
res/
ชื่อไดเรกทอรีแต่ละรายการต้องเป็นไปตามรูปแบบต่อไปนี้
<resource type>-b+<language code>[+<country code>]
เช่น values-b+es/
มีสตริง
ทรัพยากรสำหรับภาษาที่มีรหัสภาษา es
ในทำนองเดียวกัน
mipmap-b+es+ES/
มีไอคอนสำหรับภาษาที่มี es
รหัสภาษาและรหัสประเทศ ES
Android โหลดทรัพยากรที่เหมาะสมตามการตั้งค่าภาษาของ อุปกรณ์ในระหว่างรันไทม์ สำหรับข้อมูลเพิ่มเติม โปรดดู ระบุแหล่งข้อมูลอื่น
หลังจากที่คุณตัดสินใจเลือกภาษาที่จะรองรับแล้ว ให้สร้างไดเรกทอรีย่อยของทรัพยากรและ เช่น
MyProject/ res/ values/ strings.xml values-b+es/ strings.xml mipmap/ country_flag.png mipmap-b+es+ES/ country_flag.png
เติมข้อมูลไฟล์ทรัพยากรด้วยทรัพยากรที่แปลแล้ว ต่อไปนี้เป็นตัวอย่างของไฟล์ทรัพยากรรูปภาพและสตริงที่แปลแล้ว
สตริงภาษาอังกฤษ (ภาษาเริ่มต้น) ใน /values/strings.xml
:
<resources> <string name="hello_world">Hello World!</string> </resources>
สตริงภาษาสเปน (ภาษา es
ภาษา) ใน /values-b+es/strings.xml
:
<resources> <string name="hello_world">¡Hola Mundo!</string> </resources>
ไอคอนธงชาติสหรัฐอเมริกา (ภาษาเริ่มต้น) ใน
/mipmap/country_flag.png
:
![ไอคอนธงของ
สหรัฐอเมริกา](https://developer.android.com/static/images/training/languages_us_flag.png?authuser=9&hl=th)
รูปที่ 2 ไอคอนที่ใช้สำหรับภาษาเริ่มต้น (en_US)
ไอคอนธงชาติสเปน (ภาษาes_ES
) ใน
/mipmap-b+es+ES/country_flag.png
:
![ไอคอนธงของ
สเปน](https://developer.android.com/static/images/training/languages_es_flag.png?authuser=9&hl=th)
รูปที่ 3 ไอคอนที่ใช้สำหรับภาษา es_ES
หมายเหตุ: คุณสามารถใช้ตัวระบุการกำหนดค่า เช่น ตัวระบุสถานที่ ในทรัพยากรทุกประเภท ตัวอย่างเช่น คุณอาจต้องการ ให้เวอร์ชันแปลของบิตแมปที่ถอนออกได้ ดูข้อมูลเพิ่มเติมได้ที่แปลแอป
ใช้แหล่งข้อมูลในแอป
อ้างอิงทรัพยากรในซอร์สโค้ดและไฟล์ XML อื่นๆ โดยใช้
แอตทริบิวต์ name
ของทรัพยากรแต่ละรายการ
R.<resource type>.<resource name>
มีให้เลือกหลากหลาย
ของเมธอดที่ยอมรับทรัพยากร ด้วยวิธีนี้ ดังที่แสดงในตัวอย่างต่อไปนี้:
Kotlin
// Get a string resource val hello = resources.getString(R.string.hello_world) // Or supply a string resource to a method that requires a string TextView(this).apply { setText(R.string.hello_world) }
Java
// Get a string resource String hello = getResources().getString(R.string.hello_world); // Or supply a string resource to a method that requires a string TextView textView = new TextView(this); textView.setText(R.string.hello_world);
ในไฟล์ XML คุณสามารถอ้างอิงทรัพยากรด้วยไวยากรณ์ได้
@<resource type>/<resource name>
เมื่อใดก็ตามที่ XML
จะยอมรับค่าที่เข้ากันได้ ดังที่แสดงในตัวอย่างต่อไปนี้
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/country_flag" />
หมายเหตุ: เพื่อให้มั่นใจว่าการตั้งค่าภาษาของผู้ใช้จะได้รับการจัดลําดับความสําคัญ
ให้ระบุภาษาที่แอปของคุณรองรับโดยใช้พร็อพเพอร์ตี้ resConfigs
ให้ถูกต้อง สำหรับ
ข้อมูลเพิ่มเติม โปรดดู
ระบุภาษาที่แอปของคุณรองรับ
จัดรูปแบบข้อความในข้อความ
หนึ่งในงานที่พบบ่อยที่สุดในแอปคือการจัดรูปแบบข้อความ ข้อความที่แปลแล้ว ที่มีการจัดรูปแบบด้วยการแทรกข้อความและข้อมูลตัวเลขลงในตำแหน่งที่เหมาะสม แต่น่าเสียดายที่เมื่อจัดการกับข้อมูล RTL UI หรือ RTL การจัดรูปแบบอย่างง่ายสามารถ แสดงผลเป็นข้อความที่ไม่ถูกต้องหรือไม่สามารถอ่านได้
ภาษาต่างๆ เช่น อาหรับ ฮิบรู เปอร์เซีย และอูรดู จะใช้เป็น RTL อย่างไรก็ตาม องค์ประกอบบางอย่าง เช่น ตัวเลข และองค์ประกอบที่ฝัง ข้อความ LTR จะเขียนเป็น LTR ภายในข้อความ RTL ภาษาที่ใช้ตัวอักษร LTR ซึ่งรวมถึงภาษาอังกฤษจะเป็นแบบ 2 ทิศทางเช่นกัน เนื่องจากอาจมีสคริปต์ RTL แบบฝังซึ่งต้องแสดง RTL
แอปมักสร้างอินสแตนซ์ของข้อความที่อยู่ฝั่งตรงข้ามที่ฝังอยู่ประเภทนี้ เช่น ด้วยการแทรกข้อมูลที่เป็นข้อความ และทิศทางของข้อความที่กำหนดเองในข้อความที่แปลแล้ว การผสมเส้นทางนี้มักไม่รวมการบอกตำแหน่งที่ชัดเจน ข้อความที่มีทิศทางตรงกันข้ามจะเริ่มต้นและสิ้นสุด ดังนั้นแอปจึงสร้างขึ้น อาจทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี
แม้ว่าโดยทั่วไป การจัดการข้อความสองทิศทางที่เป็นค่าเริ่มต้นของระบบ ข้อความตามที่คาดไว้ ข้อความอาจแสดงผลไม่ถูกต้องเมื่อแอปของคุณ จะแทรกลงในข้อความที่แปลแล้ว ต่อไปนี้เป็นตัวอย่างสถานการณ์ ตำแหน่งที่ข้อความมีแนวโน้มที่จะปรากฏไม่ถูกต้อง:
-
ข้อความที่แทรกที่จุดเริ่มต้นของข้อความ:
PERSON_NAME กำลังโทรหาคุณ
-
ข้อความที่ขึ้นต้นด้วยตัวเลข เช่น ที่อยู่หรือหมายเลขโทรศัพท์
987 654-3210
-
ข้อความที่ขึ้นต้นด้วยเครื่องหมายวรรคตอน เช่น หมายเลขโทรศัพท์
+19876543210
-
ข้อความที่ลงท้ายด้วยเครื่องหมายวรรคตอน:
แน่ใจไหม
-
ข้อความที่มีทั้ง 2 ทิศทางอยู่แล้ว
คำว่า พิพิธภัณฑ์เกี่ยวกับการ รูปแบบนี้เริ่มต้น คือภาษาฮีบรู แปลว่ากล้วย
ตัวอย่าง
สมมติว่าบางครั้งแอปจำเป็นต้องแสดงข้อความ " คุณหมายถึง %s?" โดยมีการแทรกที่อยู่แทนที่ %s ขณะรันไทม์ แอปรองรับภาษา UI ที่แตกต่างกัน ดังนั้นข้อความจะมาจากภาษาเฉพาะ และใช้ทิศทาง RTL เมื่ออุปกรณ์ตั้งค่าเป็น RTL เช่น สำหรับภาษาฮีบรู UI ข้อความจะปรากฏดังนี้
NEWLINEホテ ลบประวัติโดยไปที่ %s?
แต่ที่อยู่ที่แนะนำอาจมาจากฐานข้อมูลที่ไม่มีข้อความ ในภาษาของประเทศนั้นๆ ตัวอย่างเช่น หากที่อยู่เป็นของสถานที่ ในรัฐแคลิฟอร์เนีย ปรากฏอยู่ในฐานข้อมูลโดยใช้ข้อความภาษาอังกฤษ หากคุณแทรกพารามิเตอร์ ที่อยู่ "15 Bay Street, Laurel, CA" ลงในข้อความ RTL โดยไม่ให้ การแนะนำเกี่ยวกับทิศทางข้อความ ผลลัพธ์ไม่เป็นไปตามที่คาดหวังหรือไม่ถูกต้อง:
六➔ בבריค์ต้องการลบ ל 15 Bay Street, Laurel, CA?
บ้านเลขที่ปรากฏทางด้านขวาของที่อยู่ ไม่ใช่ ออกตามที่ควรจะเป็น ทำให้บ้านเลขที่ดูเหมือนกับไปรษณีย์แปลกๆ มากขึ้น โค้ด ปัญหาเดียวกันนี้อาจเกิดขึ้นถ้าคุณใส่ข้อความขวา (RTL) ไว้ในข้อความที่ ใช้ทิศทางข้อความ LTR
คำอธิบายและวิธีแก้ปัญหา
ปัญหาในตัวอย่างนี้เกิดขึ้นเนื่องจากตัวจัดรูปแบบข้อความไม่ ระบุว่า "15" เป็นส่วนหนึ่งของที่อยู่ ดังนั้น ระบบจึงไม่สามารถระบุได้ว่า "15" เป็นส่วนหนึ่งของข้อความ RTL ที่อยู่ก่อนข้อความ หรือข้อความ LTR ที่เข้ามา หลังจากนั้น
หากต้องการแก้ไขปัญหานี้ ให้ใช้เมธอด unicodeWrap()
จาก BidiFormatter
วิธีนี้จะตรวจหาทิศทางของสตริงและห่อหุ้มไว้ใน Unicode
อักขระการจัดรูปแบบที่ประกาศทิศทางนั้น
ข้อมูลโค้ดต่อไปนี้สาธิตวิธีใช้
unicodeWrap()
:
Kotlin
val mySuggestion = "15 Bay Street, Laurel, CA" val myBidiFormatter: BidiFormatter = BidiFormatter.getInstance() // The "did_you_mean" localized string resource includes // a "%s" placeholder for the suggestion. String.format(getString(R.string.did_you_mean), myBidiFormatter.unicodeWrap(mySuggestion))
Java
String mySuggestion = "15 Bay Street, Laurel, CA"; BidiFormatter myBidiFormatter = BidiFormatter.getInstance(); // The "did_you_mean" localized string resource includes // a "%s" placeholder for the suggestion. String.format(getString(R.string.did_you_mean), myBidiFormatter.unicodeWrap(mySuggestion));
เนื่องจาก "15" จะปรากฏภายในข้อความที่ ประกาศว่าเป็น LTR และแสดงในตำแหน่งที่ถูกต้อง:
ホテ ปลาพลโฆษณาใหม่ וกรอบ ל 15 ถนน แขวง เมือง ลอเรล แคลิฟอร์เนีย ?
ใช้เมธอด unicodeWrap()
ใน
ข้อความทุกส่วนที่คุณแทรกลงในข้อความที่แปลแล้ว ยกเว้นในกรณีต่อไปนี้
- กำลังแทรกข้อความลงในสตริงที่เครื่องอ่านได้ เช่น URI หรือคำสั่ง SQL
- คุณทราบว่าข้อความส่วนนั้นมีการรวมอย่างเหมาะสมแล้ว
หมายเหตุ: หากแอปกำหนดเป้าหมายเป็น Android 4.3 (API ระดับ 18) หรือ
ให้ใช้เวอร์ชัน BidiFormatter
ที่พบใน
Android Framework หรือไม่เช่นนั้น ให้ใช้เวอร์ชันของ
BidiFormatter
อยู่ในไลบรารีการสนับสนุน
จัดรูปแบบตัวเลข
ใช้ รูปแบบ สตริง (ไม่ใช่การเรียกเมธอด) เพื่อแปลงตัวเลขเป็นสตริงในแอป ตรรกะ:
Kotlin
var myIntAsString = "$myInt"
Java
String myIntAsString = String.format("%d", myInt);
วิธีนี้จะจัดรูปแบบตัวเลขให้เหมาะกับภาษาของคุณ ซึ่งอาจ รวมโดยใช้ชุดตัวเลขอื่น
เมื่อคุณใช้
String.format()
เพื่อสร้าง
การค้นหา SQL ในอุปกรณ์ที่ตั้งค่าเป็นภาษาที่ใช้ชุดตัวเลขของตนเอง เช่น ภาษาเปอร์เซีย
และภาษาอาหรับส่วนใหญ่ จะเกิดปัญหาหากมีพารามิเตอร์ที่ไปยังข้อความค้นหา
เป็นตัวเลข เนื่องจากหมายเลขอยู่ในรูปแบบตัวเลขของภาษา และ
ตัวเลขเหล่านี้ไม่ถูกต้องใน SQL
หากต้องการเก็บตัวเลขในรูปแบบ ASCII ไว้ และดูแลให้คำค้นหา SQL ถูกต้อง คุณจะต้องใช้
เวอร์ชันที่ทำงานหนักเกินไปของ
String.format()
ที่
มีภาษาเป็นพารามิเตอร์แรก ใช้อาร์กิวเมนต์ภาษา
Locale.US
รองรับการมิเรอร์เลย์เอาต์
ผู้ที่ใช้สคริปต์ RTL ชอบอินเทอร์เฟซผู้ใช้ RTL ซึ่งรวมถึง เมนูที่จัดชิดขวา ข้อความที่จัดชิดขวา และลูกศรไปข้างหน้าซึ่งชี้ไปที่ ออกไปแล้ว
รูปที่ 4 แสดงคอนทราสต์ระหว่างหน้าจอเวอร์ชัน LTR ภายใน แอปการตั้งค่าและคู่หู RTL:
![พื้นที่แจ้งเตือนจะอยู่ในแนวขวาใกล้มุมขวาบน
ปุ่มเมนูในแถบแอปอยู่ใกล้กับมุมซ้ายบน
เนื้อหาในส่วนหลักของหน้าจออยู่ในแนวซ้ายและปรากฏ
LTR และปุ่มย้อนกลับอยู่ใกล้มุมซ้ายล่างและ
ชี้ไปทางซ้าย](https://developer.android.com/static/images/training/basics/ltr-display.png?authuser=9&hl=th)
![พื้นที่การแจ้งเตือนจะอยู่ในแนวซ้ายใกล้กับมุมบนซ้าย
ในแถบแอปใกล้มุมขวาบน เนื้อหา
ในส่วนหลักของหน้าจอจะอยู่ในแนวขวาและปรากฏเป็นขวาไปซ้าย และ
ปุ่มย้อนกลับจะอยู่ใกล้กับมุมขวาล่างและชี้ไปยัง
ด้านขวา](https://developer.android.com/static/images/training/basics/rtl-display.png?authuser=9&hl=th)
เมื่อเพิ่มการสนับสนุน RTL ลงในแอป ให้ ประเด็นต่อไปนี้
- รองรับการมิเรอร์ข้อความ RTL เฉพาะในแอปเมื่อใช้ในอุปกรณ์ที่ใช้งาน Android 4.2 (API ระดับ 17) ขึ้นไป ดูวิธีรองรับการมิเรอร์ข้อความ ในอุปกรณ์รุ่นเก่า โปรดดูที่ให้การสนับสนุน สำหรับแอปเดิมในคู่มือนี้
- ในการทดสอบว่าแอปรองรับทิศทางข้อความขวา (RTL) หรือไม่ ทดสอบโดยใช้ตัวเลือกสำหรับนักพัฒนาแอปตามที่อธิบายไว้ในคู่มือนี้และเชิญผู้อื่น ที่ใช้สคริปต์ RTL เพื่อใช้แอปของคุณ
หมายเหตุ: หากต้องการดูหลักเกณฑ์การออกแบบเพิ่มเติมที่เกี่ยวข้องกับ การมิเรอร์เลย์เอาต์ รวมถึงรายการองค์ประกอบที่เหมาะสมและไม่เหมาะสม ในการมิเรอร์ ให้ดูที่ แบบ 2 ทิศทาง หลักเกณฑ์ดีไซน์ Material
หากต้องการมิเรอร์เลย์เอาต์ UI ในแอปให้ปรากฏเป็น RTL ในภาษา RTL โปรดทำตามขั้นตอนในส่วนต่อไปนี้
แก้ไขไฟล์บิลด์และไฟล์ Manifest
แก้ไขไฟล์ build.gradle
ของโมดูลแอปและไฟล์ Manifest ของแอป
ดังนี้
build.gradle (Module: app)
ดึงดูด
android { ... defaultConfig { targetSdkVersion 17 // Or higher ... } }
Kotlin
android { ... defaultConfig { targetSdkVersion(17) // Or higher ... } }
AndroidManifest.xml
<manifest ... > ... <application ... android:supportsRtl="true"> </application> </manifest>
หมายเหตุ: หากแอปกำหนดเป้าหมายเป็น Android 4.1.1 (API ระดับ 16) หรือ
ระบบจะไม่สนใจแอตทริบิวต์ android:supportsRtl
รวมถึงแอตทริบิวต์
ค่าแอตทริบิวต์ start
และ end
ที่ปรากฏใน
ไฟล์เค้าโครงของแอป ในกรณีนี้ การมิเรอร์เลย์เอาต์ RTL จะไม่เกิดขึ้น
ในแอปของคุณโดยอัตโนมัติ
อัปเดตทรัพยากรที่มีอยู่
แปลง left
และ right
เป็น start
และ
end
ตามลำดับในไฟล์ทรัพยากรสำหรับเลย์เอาต์ที่มีอยู่
ซึ่งจะช่วยให้เฟรมเวิร์กปรับองค์ประกอบ UI ของแอปตาม
การตั้งค่าภาษาของผู้ใช้
หมายเหตุ: ก่อนอัปเดตทรัพยากร โปรดดูวิธี ให้การสนับสนุนสำหรับแอปเดิม หรือ แอปที่กำหนดเป้าหมายเป็น Android 4.1.1 (API ระดับ 16) และต่ำกว่า
หากต้องการใช้ความสามารถในการจัดตำแหน่ง RTL ของเฟรมเวิร์ก ให้เปลี่ยนแอตทริบิวต์ใน ไฟล์เลย์เอาต์ที่ปรากฏในตาราง 1
ตาราง 1. แอตทริบิวต์สำหรับ ใช้เมื่อแอปของคุณรองรับข้อความทิศทางหลายทิศทาง
ตารางที่ 2 แสดงวิธีที่ระบบจัดการแอตทริบิวต์การจัดแนว UI โดยอิงจาก
เวอร์ชัน SDK เป้าหมาย ไม่ว่าจะเป็นแอตทริบิวต์ left
และ right
กำหนด และระบุว่าแอตทริบิวต์ start
และ end
มีการ
กำหนดไว้
ตาราง 2. ตามลักษณะการปรับแนวองค์ประกอบ UI ในเวอร์ชัน SDK เป้าหมายและแอตทริบิวต์ที่กำหนดไว้
|
ซ้ายและขวาหมายถึงอะไร | กำหนดจุดเริ่มต้นและสิ้นสุดไหม | ผลลัพธ์ |
---|---|---|---|
ใช่ | ได้ | ใช่ |
มีการใช้ start และ end กำลังลบล้าง
left และ right
|
ใช่ | ได้ | ไม่ | ใช้ left และ right แล้ว |
ใช่ | ไม่ได้ | ใช่ | ใช้ start และ end แล้ว |
ไม่ | ได้ | ใช่ |
ใช้ left และ right (start และ
ระบบจะไม่พิจารณา end )
|
ไม่ | ใช่ | ไม่ | ใช้ left และ right แล้ว |
ไม่ | ไม่ได้ | ใช่ |
start และ end เปลี่ยนเป็น left และ
right
|
เพิ่มแหล่งข้อมูลเกี่ยวกับเส้นทางและภาษาที่เฉพาะเจาะจง
ขั้นตอนนี้จะต้องมีการเพิ่มเลย์เอาต์ เวอร์ชันที่ถอนออกได้ และเวอร์ชันที่เฉพาะเจาะจง กำหนดค่าไฟล์ทรัพยากรที่มีค่าที่ปรับแต่งสำหรับภาษาต่างๆ และข้อความแนะนำเส้นทาง
ใน Android 4.2 (API ระดับ 17) ขึ้นไป คุณสามารถใช้ -ldrtl
(layout-direction-ขวาไปซ้าย) และ -ldltr
(layout-direction-ซ้ายไปขวา) ตัวระบุทรัพยากร เพื่อย้อนกลับ
ความเข้ากันได้กับทรัพยากรที่มีอยู่แล้ว Android เวอร์ชันเก่าจะใช้
ตัวระบุภาษาของทรัพยากร เพื่อให้อนุมานทิศทางของข้อความที่ถูกต้องได้
สมมติว่าคุณต้องการเพิ่มไฟล์เลย์เอาต์ที่เฉพาะเจาะจงเพื่อรองรับสคริปต์ RTL
เช่น ภาษาฮีบรู อาหรับ และเปอร์เซีย ในการดำเนินการนี้ ให้เพิ่ม
ไดเรกทอรี layout-ldrtl/
ในไดเรกทอรี res/
ของคุณในรูปแบบ
ที่แสดงในตัวอย่างต่อไปนี้
res/ layout/ main.xml This layout file is loaded by default. layout-ldrtl/ main.xml This layout file is loaded for languages using an RTL text direction, including Arabic, Persian, and Hebrew.
ถ้าคุณต้องการเพิ่มการออกแบบเฉพาะที่ออกแบบมาสำหรับ ข้อความภาษาอาหรับ โครงสร้างไดเรกทอรีจะมีลักษณะดังนี้
res/ layout/ main.xml This layout file is loaded by default. layout-ar/ main.xml This layout file is loaded for Arabic text. layout-ldrtl/ main.xml This layout file is loaded only for non-Arabic languages that use an RTL text direction.
หมายเหตุ: ทรัพยากรเฉพาะภาษาจะมีความสำคัญสูงกว่า ทรัพยากรเฉพาะทิศทางการจัดวาง ซึ่งมีลำดับความสำคัญเหนือค่าเริ่มต้น ที่ไม่ซับซ้อน
ใช้วิดเจ็ตที่รองรับ
สำหรับ Android 4.2 (API ระดับ 17) องค์ประกอบ UI ของเฟรมเวิร์กส่วนใหญ่รองรับ RTL
ทิศทางข้อความโดยอัตโนมัติ อย่างไรก็ตาม องค์ประกอบต่างๆ ของเฟรมเวิร์ก เช่น
ViewPager
ไม่รองรับข้อความ RTL
เส้นทางการเรียนรู้
วิดเจ็ตบนหน้าจอหลักรองรับทิศทางข้อความขวาไปซ้ายตราบเท่าที่
ไฟล์ Manifest ที่เกี่ยวข้องจะมีการกำหนดแอตทริบิวต์
android:supportsRtl="true"
ให้การสนับสนุนสำหรับแอปเดิม
หากแอปกำหนดเป้าหมายเป็น Android 4.1.1 (API ระดับ 16) หรือต่ำกว่า ให้ใส่
แอตทริบิวต์ left
และ right
นอกเหนือจาก
start
และ end
หากต้องการตรวจสอบว่าเลย์เอาต์ต้องใช้ทิศทางข้อความขวาไปซ้ายหรือไม่ ให้ใช้ ตรรกะต่อไปนี้
Kotlin
private fun shouldUseLayoutRtl(): Boolean { return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { View.LAYOUT_DIRECTION_RTL == layoutDirection } else { false } }
Java
private boolean shouldUseLayoutRtl() { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { return View.LAYOUT_DIRECTION_RTL == getLayoutDirection(); } else { return false; } }
หมายเหตุ: ใช้เวอร์ชัน 23.0.1 เพื่อหลีกเลี่ยงปัญหาความเข้ากันได้ หรือสูงกว่า แอนดรอยด์ เครื่องมือสร้าง SDK
ทดสอบโดยใช้ตัวเลือกสำหรับนักพัฒนาแอป
ในอุปกรณ์ที่ใช้ Android 4.4 (API ระดับ 19) ขึ้นไป คุณสามารถเปิดใช้ บังคับทิศทางการจัดวาง RTL ใน ตัวเลือกสำหรับนักพัฒนาแอปในอุปกรณ์ การตั้งค่านี้ ช่วยให้คุณเห็นข้อความที่ใช้สคริปต์ LTR เช่น ข้อความภาษาอังกฤษ ใน RTL
อัปเดตตรรกะแอป
ส่วนนี้จะอธิบายแง่มุมเฉพาะเกี่ยวกับตรรกะของแอปสำหรับ อัปเดตเมื่อปรับแอปให้รองรับการรับส่งข้อความหลายทิศทาง
การเปลี่ยนแปลงพร็อพเพอร์ตี้
วิธีจัดการการเปลี่ยนแปลงพร็อพเพอร์ตี้ที่เกี่ยวข้องกับ RTL เช่น เลย์เอาต์
ทิศทาง พารามิเตอร์เลย์เอาต์ ระยะห่างจากขอบ ทิศทางข้อความ การจัดข้อความ หรือ
การจัดตำแหน่งที่ถอนออกได้
onRtlPropertiesChanged()
Callback Callback นี้จะช่วยให้คุณสามารถดูทิศทางของเลย์เอาต์ปัจจุบันและ
อัปเดตออบเจ็กต์ View
ของกิจกรรมให้สอดคล้องกัน
ยอดดู
หากคุณกำลังสร้างวิดเจ็ต UI ที่ไม่ได้เป็นส่วนหนึ่งของกิจกรรมโดยตรง ดูลำดับชั้น เช่น กล่องโต้ตอบหรือองค์ประกอบ UI ที่คล้ายข้อความโทสต์ ให้ตั้งค่า ทิศทางการจัดวางตามบริบท ข้อมูลโค้ดต่อไปนี้ สาธิตวิธีทำขั้นตอนนี้ให้เสร็จสมบูรณ์:
Kotlin
val config: Configuration = context.resources.configuration view.layoutDirection = config.layoutDirection
Java
final Configuration config = getContext().getResources().getConfiguration(); view.setLayoutDirection(config.getLayoutDirection());
มีหลายเมธอดสำหรับคลาส View
ที่ต้องมีฟังก์ชันเพิ่มเติม
การพิจารณา:
onMeasure()
- การวัดยอดดูอาจแตกต่างกันไปตามทิศทางข้อความ
onLayout()
- หากสร้างการติดตั้งใช้งานเลย์เอาต์ของตัวเอง คุณจะต้องเรียกใช้
super()
ในonLayout()
เวอร์ชันของคุณและปรับ ตรรกะที่กำหนดเองของคุณเพื่อรองรับสคริปต์ RTL onDraw()
- หากคุณกำลังใช้มุมมองที่กำหนดเองหรือเพิ่มฟังก์ชันการทำงานขั้นสูงลงใน
คุณต้องอัปเดตโค้ดของคุณ
เพื่อให้สนับสนุนสคริปต์ RTL ใช้เมนู
โค้ดต่อไปนี้เพื่อระบุว่าวิดเจ็ตอยู่ในโหมด RTL หรือไม่
Kotlin
// On devices running Android 4.1.1 (API level 16) and lower, // you can call the isLayoutRtl() system method directly. fun isLayoutRtl(): Boolean = layoutDirection == LAYOUT_DIRECTION_RTL
Java
// On devices running Android 4.1.1 (API level 16) and lower, // you can call the isLayoutRtl() system method directly. public boolean isLayoutRtl() { return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); }
เนื้อหาที่ถอนออกได้
หากคุณมีอุปกรณ์ที่ถอนออกได้ที่ต้องมิเรอร์สำหรับเลย์เอาต์ RTL โปรดดำเนินการให้เสร็จสมบูรณ์ ขั้นตอนใดขั้นตอนหนึ่งต่อไปนี้ขึ้นอยู่กับเวอร์ชันของ Android ที่ทำงานอยู่ในอุปกรณ์
-
สำหรับอุปกรณ์ที่ใช้ Android 4.3 (API ระดับ 18) และต่ำกว่า
เพิ่มและกำหนดไฟล์ทรัพยากร
-ldrtl
-
ใน Android 4.4 (API ระดับ 19) ขึ้นไป ให้ใช้
android:autoMirrored="true"
เมื่อกำหนดโฆษณาที่ถอนออกได้ ซึ่งช่วยให้ระบบจัดการ การมิเรอร์เค้าโครง RTL ให้คุณได้หมายเหตุ:
android:autoMirrored
ใช้ได้กับไฟล์แบบถอนออกได้อย่างง่ายที่มีการมิเรอร์ 2 ทิศทาง เป็นเพียงภาพกราฟิกของภาพที่ถอนออกได้ทั้งหมด หากถอนออกได้ มีองค์ประกอบหลายอย่างหรือหากแสดงให้เห็นถึงการเปลี่ยนแปลงที่ถอนออกได้ของคุณ คุณสามารถทำการมิเรอร์ด้วยตนเองได้ เมื่อใดก็ตามที่ ให้ตรวจสอบกับผู้เชี่ยวชาญแบบ 2 ทิศทางเพื่อดูว่า เนื้อหาที่ถอนออกได้แบบมิเรอร์จะเป็นประโยชน์ต่อผู้ใช้
แรงโน้มถ่วง
หากโค้ดเลย์เอาต์ของแอปใช้ Gravity.LEFT
หรือ
Gravity.RIGHT
เปลี่ยนรายการเหล่านี้
ค่าไปยัง Gravity.START
และ
Gravity.END
ตามลำดับ
หากคุณมีโค้ด Kotlin หรือ Java ที่ขึ้นอยู่กับ
พร็อพเพอร์ตี้ Gravity.LEFT
หรือ Gravity.RIGHT
คุณสามารถปรับใช้การเปลี่ยนแปลงนี้ได้โดยตั้งค่า absoluteGravity
ให้ตรงกับ
layoutDirection
ตัวอย่างเช่น หากคุณกำลังใช้โค้ดต่อไปนี้
Kotlin
when (gravity and Gravity.HORIZONTAL_GRAVITY_MASK) { Gravity.LEFT -> { // Handle objects that are left-aligned. } Gravity.RIGHT -> { // Handle objects that are right-aligned. } }
Java
switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: // Handle objects that are left-aligned. break; case Gravity.RIGHT: // Handle objects that are right-aligned. break; }
เปลี่ยนเป็นค่าต่อไปนี้
Kotlin
val absoluteGravity: Int = Gravity.getAbsoluteGravity(gravity, layoutDirection) when (absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK) { Gravity.LEFT -> { // Handle objects that are left-aligned. } Gravity.RIGHT -> { // Handle objects that are right-aligned. } }
Java
final int layoutDirection = getLayoutDirection(); final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection); switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: // Handle objects that are left-aligned. break; case Gravity.RIGHT: // Handle objects that are right-aligned. break; }
ซึ่งหมายความว่าคุณสามารถเก็บโค้ดที่มีอยู่
ซึ่งจัดการผลลัพธ์ตามด้านซ้ายและ
ค่าที่ตรงกัน แม้ว่าคุณจะใช้ start
และ
end
สำหรับค่าแรงโน้มถ่วง
หมายเหตุ: เมื่อใช้การตั้งค่าแรงโน้มถ่วง ให้ใช้
Gravity.apply()
เวอร์ชันโอเวอร์โหลดที่มี
อาร์กิวเมนต์ layoutDirection
ขอบและระยะห่างจากขอบ
หากต้องการรองรับสคริปต์ RTL ในแอป ให้ทําตามแนวทางปฏิบัติแนะนําเหล่านี้ที่เกี่ยวข้องกับ ค่าระยะขอบและระยะห่างจากขอบ
-
ใช้
getMarginStart()
และgetMarginEnd()
แทนที่จะเป็น แอตทริบิวต์เฉพาะเส้นทางเทียบเท่ากับleftMargin
และrightMargin
-
เมื่อใช้
setMargins()
ให้สลับค่าของleft
และright
อาร์กิวเมนต์หากแอปตรวจพบสคริปต์ RTL -
หากแอปของคุณมีตรรกะระยะห่างจากขอบที่กำหนดเอง ให้ลบล้าง
setPadding()
และsetPaddingRelative()
รองรับค่ากำหนดภาษาที่ใช้ในแอป
ในหลายกรณี ผู้ใช้หลายภาษาตั้งค่าภาษาของระบบของตนเป็นภาษาเดียว เช่น ภาษาอังกฤษ แต่ พวกเขาต้องการเลือกภาษาอื่น สำหรับบางแอป เช่น ดัตช์ จีน หรือฮินดี ให้ความช่วยเหลือ มอบประสบการณ์ที่ดีขึ้นให้แก่ผู้ใช้เหล่านี้ Android 13 ได้เปิดตัวฟีเจอร์ต่อไปนี้สำหรับ แอปที่รองรับหลายภาษา
-
การตั้งค่าระบบ: พื้นที่ส่วนกลางที่ผู้ใช้สามารถเลือก ภาษาที่ต้องการสำหรับแต่ละแอป
แอปของคุณต้องประกาศแอตทริบิวต์
android:localeConfig
ใน ไฟล์ Manifest เพื่อบอกระบบว่ารองรับหลายภาษา ดูข้อมูลเพิ่มเติมได้ที่ วิธีการสำหรับ การสร้างทรัพยากร และประกาศในไฟล์ Manifest ของแอป -
API เพิ่มเติม: API สาธารณะเหล่านี้ เช่น
setApplicationLocales()
และgetApplicationLocales()
ในLocaleManager
อนุญาตให้แอปตั้งค่าภาษาอื่นจากภาษาของระบบที่ รันไทม์แอปที่ใช้เครื่องมือเลือกภาษาในแอปแบบกำหนดเองสามารถใช้ API เหล่านี้เพื่อให้ผู้ใช้ มอบประสบการณ์ของผู้ใช้ที่สอดคล้องกัน ไม่ว่าผู้ใช้จะเลือกภาษาใดก็ตาม การตั้งค่าเริ่มต้น นอกจากนี้ API สาธารณะยังช่วยลดจำนวนของโค้ดสำเร็จรูป และ แอปเหล่านั้นรองรับ APK แยก และยังสนับสนุนการสำรองข้อมูลอัตโนมัติ สำหรับแอปเพื่อจัดเก็บการตั้งค่าภาษาของผู้ใช้ระดับแอป
สำหรับความเข้ากันได้แบบย้อนหลังกับ Android เวอร์ชันก่อนหน้า จะมี API ที่เทียบเท่าให้ใช้งานเช่นกัน ใน AndroidX เราขอแนะนำให้ใช้ Appcompat 1.6.0-beta01 หรือ สูงขึ้น
หากต้องการเรียนรู้เพิ่มเติม โปรดดูวิธีการสำหรับ การนำเทคโนโลยี API
ดูเพิ่มเติม
แหล่งข้อมูลเพิ่มเติม
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการรองรับอุปกรณ์รุ่นเก่า โปรดดูแหล่งข้อมูลต่อไปนี้