Android : Change entire app layout directions programmatically
Asked Answered
P

10

45

How can I change entire app layout direction to RTL? I am writing an app that user must select it's language in first launch and the layout should change based on user selection to RTL or remains LTR. I used to add android:supportsRtl="true" to the AndroidManifest and android:layoutDirection="rtl" for each layout but this approach have some problems like below :

One problem is when I change the direction to RTL the ActionBar home icon or navigation button (when home as up is enabled) remains LRT and just move to the right.

I also tried to change direction programmatically and the result was the same :

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
            getWindows().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
        }

enter image description here

Is there any way to force all activities to become RTL at once or we should set direction in each activity separately?

Pseudoscope answered 9/8, 2015 at 13:15 Comment(3)
Instead of asking the user to select a language at first launch, you could create multiple string resources for different languages (these would be put in different folders, e.g: values, values-de, values-es, values-fr, values-it, etc). The language set on the user's device would be automatically detected, and the correct strings/text would be displayed for that language. As well as this, the LTR or RTL layouts would be adjusted accordingly for that language.Marigolda
I haven't language issue but the layout direction problem. Some users use they're devices with English but like they're local apps in they're native language. Assume I want to have a RTL layout with English languagePseudoscope
did you find any solution ??Drabbet
R
59

You can use this piece of code while your application's minSdk >= 17.

I used fa for Farsi, you can use other rtl language.

Configuration configuration = getResources().getConfiguration();
configuration.setLayoutDirection(new Locale("fa"));
getResources().updateConfiguration(configuration, getResources().getDisplayMetrics());
Rend answered 27/6, 2016 at 8:23 Comment(9)
It's no working. Please can you provide more code with explanation.Mulch
The code above is all I know and you must run it before calling setContentView to get it worked. What's the SDK version you are testing on?Rend
Please check this issue for more information code.google.com/p/android/issues/…Mulch
See also: #2265374Lalonde
if it did not work you should add a string to another language and it works!Quartile
i dont want all my activity support RTL..How can i do for specific activites only.Higginbotham
@Higginbotham Just add android:layoutDirection="rtl" or android:layoutDirection="locale" to the top-level tag that is <LinearLayout> or <RelativeLayout> of your specific activities.Stockade
Nice, this works in combination with Robotium to take screenshots of Arabic locale. (Running on Android 5.1 emulator)Giesser
plz add this line: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {Seaweed
C
9

Change the whole layout

 LinearLayout linrtl=(LinearLayout)findViewById(R.id.linrtl);
 linrtl.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Christopher answered 16/8, 2018 at 14:32 Comment(0)
N
7

Try code below if you want to change language in the app and change directions in views and resources on active layout:

// set Persian language in the app
setLanguage(context, "fa");

public void setLanguage(Context c, String lang) {
    Locale localeNew = new Locale(lang);
    Locale.setDefault(localeNew);

    Resources res = c.getResources();
    Configuration newConfig = new Configuration(res.getConfiguration());
    newConfig.locale = localeNew;
    newConfig.setLayoutDirection(localeNew);
    res.updateConfiguration(newConfig, res.getDisplayMetrics());

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        newConfig.setLocale(localeNew);
        c.createConfigurationContext(newConfig);
    }
}

Also, after changing the language, you need to change the directions for the already created views on the active layout. You can do this with this code:

if (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL) {
        view.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
} else {
        view.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
Nowicki answered 19/1, 2019 at 7:46 Comment(0)
T
5

The easiest and best way go to the app/res/values/styles and add below code to <style> tag, that you defined its name in android manifest for example :

<style name"YourMainThemeName" parent="Parent Theme Of Your Choice">
    <item name="android:layoutDirection">rtl</item>
    <item name="windowActionBar">false</item>
</style>

and now go to the app/manifests/AndroidManifest.xml and add below line code to <application> tag :

<application
        android:supportsRtl="true"
        android:theme="@style/YourMainThemeName">
</application>

now your layout directions is rtl and use Toolbar instead of ActionBar and define icon in the toolbar for arrowBack

Toughminded answered 6/9, 2020 at 10:55 Comment(0)
R
4
public class RtlActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Configuration configuration = getResources().getConfiguration();
        configuration.setLayoutDirection(new Locale("fa"));
        getResources().updateConfiguration(configuration, getResources().getDisplayMetrics());
    }
}

extend other activities from this class instead of AppCompatActivity:

public class MainActivity extends RtlActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //bla bla bla
    }
}

tnx Afshin.

Recusant answered 8/3, 2020 at 18:29 Comment(0)
O
3
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

Enter this code in onCreate java class of activity

Oligocene answered 10/1, 2021 at 18:5 Comment(1)
Thank you, This code is working fine now.Grenier
K
1

The back button stays in LTR mode, because it only has one resource, which is an arrow pointing to the left. You need to specify a new resource folder e.g drawable-ldrtl-hdpi and put the same icon which is pointing right in this folder.

Kipp answered 29/2, 2016 at 9:44 Comment(0)
C
1

add this class:

public class LanguageHelper {

public static void changeLocale(Resources res, String locale) {

    Configuration config;
    config = new Configuration(res.getConfiguration());

    switch (locale) {
        case "fa":
            config.locale = new Locale("fa");
            config.setLayoutDirection(new Locale("fa"));
            break;
        case "en":
            config.locale = Locale.ENGLISH;
            config.setLayoutDirection(new Locale("en"));
            break;
    }
    res.updateConfiguration(config, res.getDisplayMetrics());
}

public static Locale getLocale(Resources res) {
    Configuration config;
    config = new Configuration(res.getConfiguration());
    return config.locale;
}
}

then use above class like this(in your activity):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //========set default language as persian:start==============
    LanguageHelper.changeLocale(this.getResources(), "fa");
    //========set default language as persian:end================

  ........
 }

and your layout will be RTL.

Congener answered 21/12, 2019 at 13:25 Comment(0)
A
0

I also have this problem, i find that if your view's width set MATCH_PARENT, you should set the view's gravity with Gravity.LEFT in LTR model and set the view's gravity with Gravity.RIGHT in RTL model.

Anzio answered 6/7, 2017 at 10:3 Comment(0)
H
0

Following code will work:

    Resources your_resource = context.getResources();

    Configuration config = your_resource.getConfiguration();
    config.locale = locale;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        config.setLayoutDirection(locale);
    }

where locale is object of Locale

Histrionics answered 14/3, 2019 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.