Skip to content

Instantly share code, notes, and snippets.

@muhammad-naderi
Last active November 7, 2020 09:36
Show Gist options
  • Save muhammad-naderi/0ff264e6cc07df904bc88a9f7efbe57d to your computer and use it in GitHub Desktop.
Save muhammad-naderi/0ff264e6cc07df904bc88a9f7efbe57d to your computer and use it in GitHub Desktop.
a quick Context wraper to change locale of android app in runtime, supporting changes in direction (RTL <-> LTR)
package com.mu.tools;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
import android.os.Build;
import java.util.Locale;
/**
* Created by Muhammad on 07/01/2017.
* Main idea came from http://stackoverflow.com/questions/40221711/android-context-getresources-updateconfiguration-deprecated/40704077#40704077
*/
public class LocaleHelper extends ContextWrapper {
public LocaleHelper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ContextWrapper wrap(Context context, String language) {
Configuration config = context.getResources().getConfiguration();
if (!language.equals("")) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setSystemLocale(config, locale);
} else {
setSystemLocaleLegacy(config, locale);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLayoutDirection(locale);
context = context.createConfigurationContext(config);
} else {
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
}
}
return new LocaleHelper(context);
}
@SuppressWarnings("deprecation")
public static Locale getSystemLocaleLegacy(Configuration config){
return config.locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static Locale getSystemLocale(Configuration config){
return config.getLocales().get(0);
}
@SuppressWarnings("deprecation")
public static void setSystemLocaleLegacy(Configuration config, Locale locale){
config.locale = locale;
}
@TargetApi(Build.VERSION_CODES.N)
public static void setSystemLocale(Configuration config, Locale locale){
config.setLocale(locale);
}
}
@rmr356
Copy link

rmr356 commented Mar 2, 2017

This is not working for me, it goes back to default language whenever I restart the app, and some activities don't respond to the language change. Why could it be?

@PoojaB26
Copy link

List adapters don't respond to the language change immediately. It is reflected only on recreating the activity

@mjalijani
Copy link

this solution not worked in Google Nexus 5 . Texts are not Translated ! but Direction has changed !

@podcoder
Copy link

podcoder commented Feb 4, 2019

Hi,
Thanks for the solution.
How do you store chosen language?
It's not possible to use SharedPreferences in attachBaseContext method.

I know it is late to reply, but this might help someone else looking for the same.
Let say you have a DialogInterface menu from which you choose the languages.
@Override public void onClick(DialogInterface dialog, int which) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(Your_Context); SharedPreferences.Editor editor = sharedPreferences.edit(); switch (which) { case 0: editor.putString("language","en");; break; case 1: editor.putString("language","fr"); break; case 2: editor.putString("language","fa"); break; default: editor.putString("language","en"); } editor.commit(); recreate(); dialog.dismiss(); }
and then while calling the @Override protected void attachBaseContext(Context newBase) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(newBase); String lang = sharedPreferences.getString("language", "en"); super.attachBaseContext(MyContextWrapper.wrap(newBase,lang)); }

@musso
Copy link

musso commented Nov 7, 2020

any jetpack compose version ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment