31

So I have a language setting in my application. When the language is switched, I would like all the textviews etc to change language immediately. Currently I just change the locale in the configuration, so the language has changed when the user restarts the activity.

An ugly solution to my problem would be to make each textview load the new resources each time the language is changed. Is there a better solution? Perhaps a neat way to discretely restart the activity? Or maybe just force reload of the resources?

CJBS
  • 15,147
  • 6
  • 86
  • 135
pgsandstrom
  • 14,361
  • 13
  • 70
  • 104

6 Answers6

19

In your AndroidManifest.xml, add this attribute to your Activity

android:configChanges="locale"

In your activity override onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
  // refresh your views here
  super.onConfigurationChanged(newConfig);
}

https://developer.android.com/guide/topics/manifest/activity-element.html#config

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Jim Blackler
  • 22,946
  • 12
  • 85
  • 101
  • Is this supposed to trigger when I call resource.updateConfiguration()? Im currently not having any success with getting the onConfigurationChanged() to run. :'( – pgsandstrom Apr 15 '10 at 10:52
  • 1
    onConfigurationChanged() should trigger when the language is changed. Actually just looking back there is a red flag in your question which I missed first time, "I have a language setting in my application". Does this mean you are not using the Android device-wide language setting facility? – Jim Blackler Apr 15 '10 at 11:45
  • 1
    Im not sure what you mean? But I do use the locale of the phone when the app first starts, and I have several resources marked for example values-en, values-fr, values-de etc. I just still want to the user to be able to have my app in a different language then the phone. I dont know why, but some users have requested this feature. – pgsandstrom Apr 15 '10 at 11:57
  • 3
    Aren't users annoying? I often think we'd be better off without them :-) Anyway if you have rolled your own language selector, why are you having difficulty refreshing your layouts? – Jim Blackler Apr 15 '10 at 12:15
  • True :P I am not using my completely own language support. Im still using resource.updateConfiguration(), and Im not sure why this isnt picked up by onConfigurationChanged(). – pgsandstrom Apr 15 '10 at 13:14
  • 3
    I don't undeststand how to refresh the views. I store locales in shared prefs and load it in onConfigurationChanged but nothing refresh after choosing new locale. – emeraldhieu Jul 28 '11 at 09:58
  • 7
    @JimBlackler What do you mean "refresh your views here"? Does that happen automatically using the language resource file, or do I have to do it manually for each view myself? – IgorGanapolsky Jun 17 '14 at 16:39
  • Did not reaload fragments at all – IntoTheDeep Jun 14 '16 at 10:07
  • 1
    Use android:configChanges="locale|layoutDirection" in xml if not getting callback to onConfigurationChanged. – Hradesh Kumar Apr 27 '17 at 06:53
  • what about: refresh your views here – Văn Quyết Jan 18 '19 at 16:53
11

I think the question is switching language in runtime for the app and displaying localized messages in UI. android:configChanges="locale" calls onConfigurationChanged if the system locale is changed (in setting of your device) while the app is running, and not if you change locale in the code for your app, which I guess is what you want to accomplish. That's why it's not refreshing.

MSquare
  • 6,311
  • 4
  • 31
  • 37
7

Here is the method I use during every activity onCreate() or onResume() depending on my needs (if my activity will be resuming after user changed language settings or will always be created with language already set):

From there I just refresh the view manually or from onConfigurationChanged() which get called after this method finishes.

public static void changeLocale(Activity activity, String language)
{
    final Resources res = activity.getResources();
    final Configuration conf = res.getConfiguration();
    if (language == null || language.length() == 0)
    {
        conf.locale = Locale.getDefault();
    }
    else
    {
        final int idx = language.indexOf('-');
        if (idx != -1)
        {
            final String[] split = language.split("-");
            conf.locale = new Locale(split[0], split[1].substring(1));
        }
        else
        {
            conf.locale = new Locale(language);
        }
    }

    res.updateConfiguration(conf, null);
}
3c71
  • 4,313
  • 31
  • 43
0
public void settingLocale(Context context, String language) {

Locale locale;

Configuration config = new Configuration();

 if(language.equals(LANGUAGE_ENGLISH)) {

    locale = new Locale("en");

    Locale.setDefault(locale);

    config.locale = locale;

}else if(language.equals(LANGUAGE_ARABIC)){

    locale = new Locale("hi");

    Locale.setDefault(locale);

    config.locale = locale;

}

context.getResources().updateConfiguration(config, null);

// Here again set the text on view to reflect locale change

// and it will pick resource from new locale

tv1.setText(R.string.one); //tv1 is textview in my activity

}
Robert
  • 5,278
  • 43
  • 65
  • 115
ubhusri
  • 52
  • 5
0

Assuming you're changing the language through something like

private void updateLocale(@NonNull final Context context,
                          @NonNull final Locale newLocale) {
    final Resources resources = context.getResources();
    final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
    final Configuration configuration = resources.getConfiguration();
    configuration.locale = newLocale;
    resources.updateConfiguration(configuration, displayMetrics);
    Locale.setDefault(newLocale);
}

You'll need to call Activity.recreate() in all currently open activities, which is what would happen if the user changed the system language while you were not subscribing to android:configChanges="locale".

Thorbear
  • 2,303
  • 28
  • 23
  • 2
    An explanation for downvotes would be much appreciated. – Thorbear Nov 15 '17 at 17:15
  • I am using this way to switch the app language. but the app doesn't load my 'vi' resource when the system language is in 'en'. Do you know why? – Nguyen Mar 26 '21 at 04:18
  • @Nguyen 'vi' as in "U.S. Virgin Islands"? According to Android Studio the correct locale for that is 'en-rVI'. Where are your resources saved? And in order for the app to load those resources, you'll need the locale to be 'en-rVI', not just 'en', otherwise it will go with normal 'en' resources or the default ones. – Thorbear Mar 26 '21 at 21:06
0

I'm not sure why this isn't picked up by onConfigurationChanged().

Hey, sandis, do you mean the method onConfigurationChanged() doesn't called in your activity when you changed the language? I met the same problem. The problem maybe this: when we change the language, the activity goes to onDestroy()(you can try this), so there is nobody to call onConfigurationChanged(). When we launch the activity again, the onCreate() is called, not the onConfigurationChanged(). There maybe something different in locale change and orientation change.

Baz
  • 36,440
  • 11
  • 68
  • 94
  • 1
    Really sorry, it's my mistake: my activity is an embedded activity of an tabactivity, when add android:configChanges="locale" to the tabactivity, it works well, it will not goes to onDestroy() when change the language, and will call onConfigurationChanged() in the tabactivity, but this method cann't called in the embedded activity. – himalayagiant Nov 30 '11 at 06:19