Identifying RTL language in Android

AndroidRight to-Left

Android Problem Overview


Is there a way to identify RTL (right-to-left) language, apart from testing language code against all RTL languages?

Since API 17+ allows several resources for RTL and LTR, I assume, there should be a way, at least from API 17.

Android Solutions


Solution 1 - Android

Get it from Configuration.getLayoutDirection():

Configuration config = getResources().getConfiguration();
if(config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
    //in Right To Left layout
}

Solution 2 - Android

@cyanide's answer has the right approach but a critical bug.

Character.getDirectionality returns the Bi-directional (bidi) character type. Left-to-right text is a predictable type L and right-to-left is also predictably type R. BUT, Arabic text returns another type, type AL.

I added a check for both type R and type AL and then manually tested every RTL language Android comes with: Hebrew (Israel), Arabic (Egypt), and Arabic (Israel).

As you can see, this leaves out other right-to-left languages, so I was concerned that as Android adds these languages, there might have a similar issue and one might not notice right away.

So I tested manually each RTL language.

  • Arabic (العربية) = type AL
  • Kurdish (کوردی) = type AL
  • Farsi (فارسی) = type AL
  • Urdu (اردو) = type AL
  • Hebrew (עברית) = type R
  • Yiddish (ייִדיש) = type R

So it looks like this should work great:

public static boolean isRTL() {
    return isRTL(Locale.getDefault());
}

public static boolean isRTL(Locale locale) {
    final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
    return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
           directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
}

Thanks @cyanide for sending me the right direction!

Solution 3 - Android

If you're using the support library, you can do the following:

if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL) {
    // The view has RTL layout
} else {
    // The view has LTR layout
}

Solution 4 - Android

You can use TextUtilsCompat from the support library.

Solution 5 - Android

There's a really simple way to check the layout direction of a view, but it falls back to LTR on pre API 17 devices:

ViewUtils.isLayoutRtl(View view);

the ViewUtils class comes bundled with the support v7 library, so it should be available already if you're using the appcompat library.

Solution 6 - Android

You can check like this if you want to check for API lower than 17

boolean isRightToLeft = TextUtilsCompat.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;

OR for API 17 or above

boolean isRightToLeft = TextUtils.getLayoutDirectionFromLocale(Locale
               .getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL;

Solution 7 - Android

I gathered many information and finally made my own, hopefully complete, RTLUtils class.

It allows to know if a given Locale or View is 'RTL' :-)

package com.elementique.shared.lang;

import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

import android.support.v4.view.ViewCompat;
import android.view.View;

public class RTLUtils
{

	private static final Set<String> RTL;

	static
	{
		Set<String> lang = new HashSet<String>();
		lang.add("ar"); // Arabic
		lang.add("dv"); // Divehi
		lang.add("fa"); // Persian (Farsi)
		lang.add("ha"); // Hausa
		lang.add("he"); // Hebrew
		lang.add("iw"); // Hebrew (old code)
		lang.add("ji"); // Yiddish (old code)
		lang.add("ps"); // Pashto, Pushto
		lang.add("ur"); // Urdu
		lang.add("yi"); // Yiddish
		RTL = Collections.unmodifiableSet(lang);
	}

	public static boolean isRTL(Locale locale)
	{
		if(locale == null)
			return false;
		
		// Character.getDirectionality(locale.getDisplayName().charAt(0))
		// can lead to NPE (Java 7 bug)
		// https://bugs.openjdk.java.net/browse/JDK-6992272?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab
		// using hard coded list of locale instead
		return RTL.contains(locale.getLanguage());
	}

	public static boolean isRTL(View view)
	{
		if(view == null)
			return false;
		
		// config.getLayoutDirection() only available since 4.2
		// -> using ViewCompat instead (from Android support library)
		if (ViewCompat.getLayoutDirection(view) == View.LAYOUT_DIRECTION_RTL)
		{
			return true;
		}
		return false;
	}
}

Solution 8 - Android

You can detect if a string is RTL/LTR with Bidi. Example:

import java.text.Bidi;

Bidi bidi = new Bidi( title, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT );

if( bidi.isLeftToRight() ) {
   // it's LTR
} else {
   // it's RTL
}

Solution 9 - Android

For more precise control over your app UI in both LTR and RTL mode, Android 4.2 includes the following new APIs to help manage View components:

android:layoutDirection — attribute for setting the direction of a component's layout.
android:textDirection — attribute for setting the direction of a component's text.
android:textAlignment — attribute for setting the alignment of a component's text.
getLayoutDirectionFromLocale() — method for getting the Locale-specified direction

Thus getLayoutDirectionFromLocale() should help you out. Refer the sample code here : https://android.googlesource.com/platform/frameworks/base.git/+/3fb824bae3322252a68c1cf8537280a5d2bd356d/core/tests/coretests/src/android/util/LocaleUtilTest.java

Solution 10 - Android

Just use this code:

 public static boolean isRTL() {
   return isRTL(Locale.getDefault());
 }

 public static boolean isRTL(Locale locale) {
  final int directionality = Character.getDirectionality(locale.getDisplayName().charAt(0));
  return directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
       directionality == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC;
 }

 if (isRTL()) {
   // The view has RTL layout
 }
 else {
   // The view has LTR layout
 }

This will work for all Android API lavels.

Solution 11 - Android

Thanks to all.

If you look at the code of LayoutUtil.getLayoutDirectionFromLocale() (and, I assume Confuiguration.getLayoutDirection() as well), it ends up with analysing the starting letter of locale display name, using Character.getDirectionality.

Since Character.getDirectionality was around from Android 1, the following code will be compatible with all Android releases (even those, not supporting RTL correctly :)):

public static boolean isRTL() {
	return isRTL(Locale.getDefault());
}

public static boolean isRTL(Locale locale) {
	 return
		Character.getDirectionality(locale.getDisplayName().charAt(0)) ==
			Character.DIRECTIONALITY_RIGHT_TO_LEFT; 
}

Solution 12 - Android

When building library you also always need to check if application is supporting RTL by using

(getApplicationInfo().flags &= ApplicationInfo.FLAG_SUPPORTS_RTL) != 0

When application is running on RTL locale, but it isn't declared in manifest android:supportsRtl="true" then it is running in LTR mode.

Solution 13 - Android

This will work in all SDKS:

private boolean isRTL() {
	Locale defLocale = Locale.getDefault();
	return  Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT;
}

Solution 14 - Android

Native RTL support in Android 4.2

    public static ComponentOrientation getOrientation(Locale locale) 
    {
            // A more flexible implementation would consult a ResourceBundle
            // to find the appropriate orientation.  Until pluggable locales
            // are introduced however, the flexiblity isn't really needed.
            // So we choose efficiency instead.
            String lang = locale.getLanguage();
            if( "iw".equals(lang) || "ar".equals(lang)
                || "fa".equals(lang) || "ur".equals(lang) )
            {
                return RIGHT_TO_LEFT;
            } else {
                return LEFT_TO_RIGHT;
            }
    }

Solution 15 - Android

Easily you can use this :

 if (getWindow().getDecorView().getLayoutDirection()== View.LAYOUT_DIRECTION_RTL) {
        // The view has RTL layout
    } else {
        // The view has LTR layout
    }

Solution 16 - Android

Because English language devices are supporting RTL, you can use this code in your MainActivity to change device language to english and you don't need to "supportRTL" code.

String languageToLoad  = "en"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncyanideView Question on Stackoverflow
Solution 1 - AndroidMorrison ChangView Answer on Stackoverflow
Solution 2 - AndroidTim TruemanView Answer on Stackoverflow
Solution 3 - AndroidMichaelView Answer on Stackoverflow
Solution 4 - AndroidElyess AboudaView Answer on Stackoverflow
Solution 5 - AndroidJohannesView Answer on Stackoverflow
Solution 6 - AndroidInzimam Tariq ITView Answer on Stackoverflow
Solution 7 - AndroidPascalView Answer on Stackoverflow
Solution 8 - AndroidRonTLVView Answer on Stackoverflow
Solution 9 - AndroidSKNView Answer on Stackoverflow
Solution 10 - AndroidItiel MaimonView Answer on Stackoverflow
Solution 11 - AndroidcyanideView Answer on Stackoverflow
Solution 12 - AndroidJedoView Answer on Stackoverflow
Solution 13 - AndroidGil SHView Answer on Stackoverflow
Solution 14 - AndroidAmit PrajapatiView Answer on Stackoverflow
Solution 15 - AndroidBahaa S AlkhteebView Answer on Stackoverflow
Solution 16 - AndroidTaha khozooieView Answer on Stackoverflow