RTL Support in Android
While most of the languages in the world are written from left to right, there are several languages are written in Right-to-Left writing (RTL) system. The most widespread RTL are Arabic script, Hebrew alphabet and Syriac alphabet.
Android has full native support of RTL layout/text orientation since SDK 17 (Android 4.2 Jelly Bean), according to the official blog, getting started is easy.
- Set targetSdkVersion or minSdkVersion to 17 or higher in the uses-sdk tag of AndroidManifest.xml
- Declare android:supportsRtl=”true” in the application tag of AndroidManifest.xml
- Replace all the occurrences of layout attributes that contains ‘left’ and ‘right’ to ‘start’ and ‘end’ respectively. For example, android:paddingLeft should become android:paddingStart.
- If the app needs to support devices earlier than 4.2, then you should add the ‘start’ and ‘end’ in addition to the ‘left’ and ‘right’. For example, you will have both android:paddingLeft and android:paddingStart.
Now hit compile button, cross finger, pray that your app supports RTL and be happy ever after? Unfortunately there are a few things you need to pay attention to.
The mirrored image
Android RTL engine automatically reverses the horizontal layout arrangement, so you can see the placement of the UI items is now from right to left.
It looks fine in this case, but what happen if there is a directional UI item? i.e., the back button.
Although the layout direction is reversed, the RTL engine will not automatically reverse(mirror) the drawable, and we need to manually define a mirrored drawable in this case, the easiest way is via resource qualifier ‘ldrtl’. If the original back button drawable is located as /res/drawable/ic_back.xml (I am using vector drawable), we can then add the mirrored drawable at /res/drawable-ldrtl/ic_back.xml and this mirrored drawable will be used and rendered in the RTL mode.
Not only drawable resources, you can also use ‘ldrtl’ qualifier for other resources such as colours, layouts, and strings. It is really up to the developer to define what kind of resources to be used for RTL mode.
I do not know Arabic, how can I test my app during development?
Android turns into RTL layout mode when the phone language is set to Arabic or any other RTL languages, but for developer who does not understand RTL language, how can we test the RTL layout during development? Fortunately there is a handy tool in the developer option that forces RTL layout direction in any languages, the name and the location of the settings differs from phone to phone, in my device it is called ‘Force RTL layout direction’.
How do I programmatically change my app to RTL mode?
If your app has a settings option to change language within the app, it would make sense to also change to the appropriate layout direction according to the chosen language. There is a new API being added to Configuration class since SDK 17, and we can use it to programatically change the layout direction.
Locale locale = getLocale();
Resources resources =context.getResources();
Configuration config = resources.getConfiguration();
config.locale = locale;
if (Build.VERSION.SDK_INT >= 17) {
config.setLayoutDirection(locale);
}
resources.updateConfiguration(config, resources.getDisplayMetrics());
If getLocale() returns a locale that requires RTL layout mode (i.e., Arabic) config.setLayoutDirection(locale) will change the app to RTL layout direction mode accordingly.