Try with recreate() on your activity. This approach was successful in my case. If you are on Fragment, then use getActivity().recreate();
SharedPreferences.Editor editor = prefs.edit();
editor.putString(Constants.APP_STATE.SAVED_LOCALE, localeString);
editor.apply();
getActivity().recreate();
Override following method of your activity:
@Override
protected void attachBaseContext(Context newBase) {
SharedPreferences prefs = newBase.getSharedPreferences(Constants.APP_STATE.STATE_SHARED_PREFERENCES, MODE_PRIVATE);
String localeString = prefs.getString(Constants.APP_STATE.SAVED_LOCALE, Constants.DEFAULTS.DEFAULT_LOCALE);
Locale myLocale = new Locale(localeString);
Locale.setDefault(myLocale);
Configuration config = newBase.getResources().getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
config.setLocale(myLocale);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N){
Context newContext = newBase.createConfigurationContext(config);
super.attachBaseContext(newContext);
return;
}
} else {
config.locale = myLocale;
}
super.attachBaseContext(newBase);
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
When user set wanted locale, what you want to do is to save it into some string in SharedPreferences and call recreate() of activity. This will then call attachBaseContext(Context context) and in this method proper locale will be set to configuration, then new context will be created with this configuration. After that, new context will be sent to super class which will update application context and proper locale will be shown.
It is also good because locale is automatically set when starting app next time.