Follow the steps below to deal with Localization programmatically.
Create BaseActivity
that extends from AppCompactActivity
then extend from the BaseActivity
in all other Activities.
in the BaseActivity
we will attach the context of the whole activities of the app and also deals with configration changes as rotation.
public class BaseActivity extends AppCompatActivity {
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
}
@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
super.applyOverrideConfiguration(overrideConfiguration);
}
}
in all activities extend from this BaseActivity
:
public class MainActivity extends BaseActivity {
...
}
create App class that will extends Application
in this class we will override attachBaseContext
public class App extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
}
also don't forget to add it to manifest inside the application tag
<application
android:name=".App"
.../>
Add the LocaleHelper class to your project.
at first before we change the language we save it in a SharedPreferences using setLanguage
method in the LanguageUtils
class.
public class LocaleHelper {
public static Context changeLanguage(final Context context, final String toLang) {
//at first save the desired language at shared preference
setLanguage(context, toLang);
final Locale toLocale = new Locale(toLang);
Locale.setDefault(toLocale);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
return updateResourcesForO(context, toLocale);
}
else{
return updateResources(context, toLocale);
}
}
@TargetApi(Build.VERSION_CODES.O)
private static Context updateResourcesForO(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
LocaleList localeList = new LocaleList(locale);
LocaleList.setDefault(localeList);
configuration.setLocales(localeList);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
private static Context updateResources(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
configuration.setLayoutDirection(locale);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
LnaguageUtils
: is a java class that helps us to save the current language in SharedPreferences.
public class LanguageUtils {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
private static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences("APP_PREF", Context.MODE_PRIVATE);
}
public static void setLanguage(Context context, String language) {
SharedPreferences.Editor editor = getSharedPreferences(context).edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
public static String getLanguage(Context context) {
return getSharedPreferences(context).getString(SELECTED_LANGUAGE, "sys");
}
}
"sys"
means System default localization.
Edit attachBaseContext
method in the BaseActivity
and the App
class to attach the context with the new resources with the desired language, like this:
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.changeLanguage(base, getLanguage(base)));
}
also the applyOverrideConfiguration
method in the BaseActivity
:
@Override
public void applyOverrideConfiguration(Configuration overrideConfiguration) {
super.applyOverrideConfiguration(getBaseContext().getResources().getConfiguration());
}
Now if you need to change the language in any activity/fragment just call:
LocaleHelper.changeLanguage(MainActivity.this, "en");
"en"
means english locale
you can find the whole supported locales here.
after you change the language don't forget to restart the app to show the new language. use the method below to restart the app:
public void recreateTask(final Context context) {
final PackageManager pm = context.getPackageManager();
final Intent intent = pm.getLaunchIntentForPackage(context.getPackageName());
final ComponentName componentName = intent.getComponent();
final Intent mainIntent = Intent.makeRestartActivityTask(componentName);
context.startActivity(mainIntent);
Runtime.getRuntime().exit(0);
}