Supporting RTL Design on Android
Tags: arabic, mobileappdevelopment, android, ui
Published: 2022-06-01 05:52:18

---
title: Supporting RTL Design on Android
published: true
date: 2021-07-26 09:40:04 UTC
tags: arabic,mobileappdevelopment,android,ui
canonical_url: 
---

Hello Android followers. Today I’ll write all my RTL ( Right to Left ) support design experiences on Android. I hope this article will save your time. Take your tea/coffee/water and let's start.

![](https://cdn-images-1.medium.com/max/1024/1*dvqOnyWiuFUwzvPkMq0QdQ.png)
_RTL Support Design_

Almost all scripts in the world are written from Left to Right. But some script like Arabic is written from Right to Left. So for the best user experience, we should support Right to Left design, too.

When a UI changed from LTR to RTL (or vice versa) it’s named “ **mirroring** ”. If you looking for a design guidelines about which UI components should be mirroring and which UI components shouldn't mirroring, you can check out [**_material.io_**](https://material.io/design/usability/bidirectionality.html#mirroring-layout).

**Some Important Points From The** [**material.io Article**](https://material.io/design/usability/bidirectionality.html#mirroring-layout)

- Numbers such as those on a clock and phone numbers are shouldn’t be mirrored.
- LTR text shouldn’t be displayed in reverse order. E.g. if a number in LTR is 123456 in RTL must be 123456, too. Don't reverse it. The direction of such texts must be LTR.
- The texts untranslated to RTL language shouldn’t be mirrored (even if it’s parts of a phrase)
- Charts and graphs shouldn’t be mirrored.
- Icons that don’t communicate direction such as a camera 📸, search 🔍, keyboard ⌨️, headset 🎧, call 📞 are shouldn’t be mirrored
- Icons containing numbers should be localized for other languages that use different numerals.
- You shouldn’t mirror slashes on images. Because the LTR slashes describe an off state for both LTR and RTL languages. E.g. No Parking
- Media playback buttons and media progress indicator shouldn't be mirrored if they refer to the direction of tape being played

The Android OS has native RTL design support since SDK 17 version. Keep in mind.

First of all, you must add android:supportsRtl="true" to the [<application>](http://developer.android.com/guide/topics/manifest/application-element.html) element in your manifest file for your app to supporting RTL design.

**Trick** : If your app supports multiple languages and if you have code snippet like _config.setLayoutDirection(Locale.US)_ you must change it. Otherwise, your app will not support the RTL design. You can change the code line like below.

![](https://cdn-images-1.medium.com/max/1024/1*9pa80I9S6fvnKQ6G-nsE4g.png)
_Setting layout direction to locale base_

After that, replace your app’s all left/right layout properties start/end with their equivalents. If you must support versions earlier than SDK 17 you should use both left/right and start/end properties in the same view. When you do this The Android OS is gonna handle your almost all views layout mirroring automatically. In my opinion, set your minSdkVersion is 21 so Android 5. Because almost all phones sdk version is over than 21 in 2021. In this article, I assume your minSdkVersion is 19 and higher.

You can feel terrible when you think about replacing all left/right properties to start/end. Stop feeling like that, calm down and keep reading. I have a trick for you.

**Trick** : Android Studio just has a tool for replacing all properties with their RTL equalivents. For doing this follow these steps.

![](https://cdn-images-1.medium.com/max/879/1*ymPu5QtDv8jAsVqTVstgrA.png)

Click right on res folder. After that hold to the cursor on Refactor finally click Add Right-to-Left (RTL) Support. When you did these a window will appear like below.

![](https://cdn-images-1.medium.com/max/524/1*YxJQQZoG_kJP4yUAs8uhxg.png)

On this window unmark Update AndroidManifest.xml and mark Replace Left/Right Properties with Start/End properties and Run it. After the operations finished a window will appear like below.

![](https://cdn-images-1.medium.com/max/682/1*n7G7Zhkyvy6TaZOxRQC3tw.png)

It shows you which layouts will be refactoring. If you want to refactor only your project layouts you can exclude other layout files from came 3rd party libraries.

![](https://cdn-images-1.medium.com/max/845/1*iaKpdDFMlKqJr-oHz7dpIg.png)

Select layout files which you don’t want to refactor, click right and exclude all. When you did these your layout files will be like below.

![](https://cdn-images-1.medium.com/max/673/1*gYnjw90hl_SXAPhN6CiTIQ.png)

After that click Do Refactor. And now your all layout properties changed with their equivalents. Check your local changes and Run Project💨. You can see your almost all layouts will be supporting RTL design.

By only these changes your app maybe can’t fully support RTL design. For a fully supported RTL design, you should pay attention to the below sections.

### Supporting Directional Resources

Android’s RTL engine reverses layout direction but doesn’t reverse resources (so drawables) automatically. So if we have a directional image we must reverse it manually.

You know android projects resources directories have some qualifiers as **-night** , **-v24** , **-v21** , **-xxhdpi** , **-ar**  . Like these also has -ldrtl qualifier meaning “layout direction right-to-left” for resources working on RTL languages.

![](https://cdn-images-1.medium.com/max/170/1*8Locp8mVleWWFyMrdYXSDA.png)
_Some resources qualifiers on the android project_

**Supporting Images, Icons**

![](https://cdn-images-1.medium.com/max/158/1*ernpA9uxsIbJSRGfyruKDA.png)
_Directional image / icon_

Suppose we have a shopping cart image like the above A option. It must be shown as the B option in RTL design. Normally we place A image as _res/drawable/ic\_cart.png_ or _res/drawable/ic\_cart.xml_ on our project. For supporting this image on RTL design firstly prepare a new directory named as _res/drawable_ **_-ldrtl_**. After that get your right to left supported image (B option) having the same name as LTR image and place it in the drawable **-ldrtl** directory. The Android OS will render the right file when loading your interfaces. It will support LTR design and RTL design both.

(Also for using some resource files in LTR design you can prepare files with -ldrtl qualifier)

**Trick** : If you are using icons as Vector Assets (files with .xml extension) you don’t need a new directory with -ldrtl qualifier. When you add **_android:autoMirrored="true"_** line in vector tag, your icon gonna has RTL support automatically. ( **This work SDK 19 and higher version.** ) So you don’t need to store 2 files in your project. In this way, your apk size will be smaller. And when you want to change your icon it will be enough to change only one file.

**Supporting Animations**

Animations that use X-axis don't work well on RTL design. You can prepare res\transition-ldrtl or res\anim-ldrtl directories and placing RTL design-supported animation files in these directories. Make sure LTR animation file and RTL animation file names are the same. For example, res\anim\ **slide\_out\_right.xml** and res\anim **-ldrtl\slide\_out\_right.xml**

### Supporting Views

**Supporting RecyclerView**

Officially supported. You don’t need to do anything in addition to the above. How wonderful, isn’t it?

**Supporting ViewPagers**

If you use ViewPager2 in your project also you can skip this section. Because ViewPager2 officially supports RTL design. Otherwise, If you use ViewPager you can support RTL design in 2 ways; rotating some views and migrating to ViewPager2.

_Rotating Views_

You need to add a new value as _locale\_viewpager\_rotation=_ **_0_** to integers.xml. After that prepare another _integers.xml_ file under the _values-ldrtl_ folder. Add _locale\_viewpager\_rotation =_ **_180_** value in this xml file. Finally _android:rotationY="@integer/locale\_viewpager\_rotation”_ code snippet to your viewpager (You can also use this method for any view). In this way, your viewpagers will be rotated on RTL design. For fully supporting may need to rotate the content of viewpager items, too. And indicators, too.

I tried this method. It isn’t an efficient solution so in my opinion just migrate to ViewPager 2.

_Migrating ViewPager2_

ViewPager2 built on RecyclerView so it has RTL support officially. So for the best solution [**migrate your ViewPager adapter to ViewPager2**](https://developer.android.com/training/animation/vp2-migration)adapter. And get benefits of ViewPager2.

Also if you use TabLayout with ViewPager you must migrate it to ViewPager2 implementation, too. You can use

{% gist https://gist.github.com/cengiztoru/1349f4a2e3eae3c779da75667b7dcb14 %}

code snippet instead of _mTabLayout.setupWithViewPager(mViewPager) ._

**Supporting TextViews**

TextView officially supports RTL design. If you use start-end properties instead of left-right it works well in RTL design. So when you setted an RTL script text to textview, text will start from right automatically.

![](https://cdn-images-1.medium.com/max/402/1*S6Uj-sLmUVLn3kqr2oG41A.png)

But if in RTL mode you set an LTR script text, textView’s text will start left like below (Even if you replaced left/right to start/end).

![](https://cdn-images-1.medium.com/max/486/1*fEdKOj5renVlpm7EOhSqdw.png)

If you don't want to this, you can add **_android:textDirection=”locale"_** attribute to your textViews. I recommend this because the screen becomes more fluid. When you did this your textViews shown as below. Even if textView’s text LTR script, it will start from right. Of course, you can combine this attribute with styles in styles.xml.

![](https://cdn-images-1.medium.com/max/492/1*r4DAB7IvfXZI1dLOh1ijrg.png)

Finally

![](https://cdn-images-1.medium.com/max/1012/1*E2lpY1gq2yPmVQEBFBgbpw.png)

In some cases, if you be obligated to setting textView direction to LTR and if you want to LTR scripts shown on right in RTL design, you can set

{% gist https://gist.github.com/cengiztoru/2fc4d4389e4e25faa41687ca6838347f %}

programmatically.

**Supporting EditTexts**

EditText officially supports RTL design. If you use start-end properties instead of left-right it works well in RTL design. So when you write an RTL script text to edittext, the edittext’s text will start from right automatically.

But when the app is in RTL mode if you write an LTR script text, editText’s text will start left like as TextView. If you don’t want to this and even in LTR scripts if you want to edditext’s text start from right you can try below options

- First of all, be careful for adding **_android:gravity_** property.
- If your edittext is inside TextInputLayout you can add **_android:textDirection=”locale”_** attribute to **TextInputLayout**. It will works like below

![](https://cdn-images-1.medium.com/max/462/1*-IGMWd7UeCSBMLcKWzMYrA.png)
_An EditText inside TextInputLayout_

If **_android:textDirection=”locale”_** not works you can try adding **android:textAlignment=”viewStart"** attribute to **TextInputEditText**

- If you have simple edittext you can add **_android:textDirection=”locale”_** attribute to your EditText. If **_android:textDirection=”locale”_** not works you can try adding **android:textAlignment=”viewStart”** attribute to EditText.
- If you want to fix the cursor to the far right of the edittext you can use below code snippet

{% gist https://gist.github.com/cengiztoru/18b4f8a52ff20e77d836b57a78085cf2 %}

**Supporting WebViews**

When you loading an HTML data/block to webView if it hasn’t got RTL support you can manipulate it by below code snippet. So it will support RTL design.

{% gist https://gist.github.com/cengiztoru/9aa0b5b681b66443a81698ba8ede8709 %}

**Supporting Custom Layouts for Specific Scripts**

If you want to add a specific version of the layout that is designed for only Arabic text, your directory structure becomes the following:

![](https://cdn-images-1.medium.com/max/707/1*CmcUDZrxYJtPO95qjsHt7A.png)

**res/layout/main.xml** This layout file is loaded by default.

**res/layout-ar/main.xml** This layout file is loaded with Arabic text.

**res/layout-ldrtl/main.xml** This layout file is loaded only for non-Arabic languages that use an RTL text direction.

**Some Code Snippets which maybe you’ll need**

- If you use _Gravity.LEFT/RIGHT_ you should replace to _Gravity.START/END_.
- If you want to learn the layout direction of a view you can obtain it by _view.layoutDirection_ code snippet
- For obtaining the layout direction of a context you can use this _context_._resources_._configuration_._layoutDirection_ code snippet.
- For changing layoutDirection you can use view._layoutDirection_ = View._LAYOUT\_DIRECTION\_RTL_ code snippet
- For checking layout direction is you can use a condition like below

{% gist https://gist.github.com/cengiztoru/5f618a7660b50ca574fd3c4e5e73bef4 %}

- For obtaining text direction of a view you can do this with _view_._textDirection. S_o you can set like _view_._textDirection = view.textDirection = View.TEXT\_DIRECTION\_RTL_
- For layout direction for specific locale you can use _TextUtils. getLayoutDirectionFromLocale (locale)_
- If you have a custom view and if you need a callback when RTL properties changed you can override the below function

{% gist https://gist.github.com/cengiztoru/e7ee6334730cac59088496f6117f761d %}

**Conclusion**

For fully supported RTL design in your app, briefly you can follow these steps

- Replace your app’s all left/right layout properties with start/end which are their equivalents.
- If you use ViewPager, just migrate ViewPager2.
- Set text direction “locale” for your text views
- Add autoMirrored = true in your icons which need to mirroring in RTL design.

Thank you for reading. If you think the article is useful please clap 👏 and share so more people benefit.

### **Keep In Touch**

- [Cengiz TORU - Istanbul, Turkey | Professional Profile | LinkedIn](https://www.linkedin.com/in/cengiztoru/)
- [cengiztoru - Repositories](https://github.com/cengiztoru?tab=repositories)

### **Sources**

- [Material Design](https://material.io/design/usability/bidirectionality.html#mirroring-layout)
- [Native RTL support in Android 4.2](https://android-developers.googleblog.com/2013/03/native-rtl-support-in-android-42.html)
- [RTL Support in Android](https://medium.com/@zhangqichuan/rtl-support-in-android-898e11f31561)
- [RTL Support on Android. Here is all you need to know](https://medium.com/android-news/rtl-support-on-android-here-is-all-you-need-know-e13f2df512e2)

### Support Layout Mirroring Developers Android