Reputation: 655
I try to setting locale in app, first run it works. But, after onCreate() (Rotate) will get reset to default language and I can't change language in app after reset.
I use SharePreference to save locale value
PrefUtils.java to get value from SharePreference
public class PrefUtil {
private static final String PREF_SETTINGS_LANGUAGE = "pref_settings_language";
public static String getLocale(Context context){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String loadLanguage = sharedPreferences.getString(PREF_SETTINGS_LANGUAGE, "");
Log.d("LoadLanguage", loadLanguage);
return loadLanguage;
}
}
MainActivity.java to set locale, I put in onCreate and onResume
private void appLocale(String localeCode){
Locale locale = new Locale(localeCode);
Locale.setDefault(locale);
Configuration configuration = getBaseContext().getResources().getConfiguration();
configuration.locale = locale;
getBaseContext().getResources().updateConfiguration(configuration, getBaseContext().getResources().getDisplayMetrics());
}
Upvotes: 0
Views: 648
Reputation: 1763
In activity class, you should override attachBaseContext(base : Context)
.
Create an abstract class BaseActivity
and extends it on MainActivity
.
By doing this you don't have to write onAttachBaseContext()
in every activity class but should extend BaseActivity
instead of AppCompatActivity
.
class BaseActivity : AppCompatActivity {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(LocaleHelper.onAttach(base))
}
}
To retain language setting you should also override attachBaseContext(base:Context)
in Application class.
class App : Application() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(LocaleHelper.onAttach(base, LocaleHelper.LANG_EN))
}
}
If you need a helper class of localization, here is the one. The code is in Kotlin, but I think you will understand.
object LocaleHelper {
private const val SELECTED_LANGUAGE = "Locale.Helper.Selected.Language"
const val LANG_EN = "en"
const val LANG_ES = "es"
val languageMap = hashMapOf(
LANG_EN to "English",
LANG_ES to "Spanish"
)
fun onAttach(context: Context): Context {
val lang = getPersistedData(context, Locale.getDefault().language)
return setLocale(context, lang)
}
fun onAttach(context: Context, defaultLanguage: String): Context {
val lang = getPersistedData(context, defaultLanguage)
return setLocale(context, lang)
}
fun getLanguage(context: Context): String? {
return getPersistedData(context, Locale.getDefault().language)
}
fun setLocale(context: Context, language: String?): Context {
persist(context, language)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResources(context, language)
} else {
updateResourcesLegacy(context, language)
}
}
private fun getPersistedData(context: Context, defaultLanguage: String): String? {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage)
}
private fun persist(context: Context, language: String?) {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
val editor = preferences.edit()
editor.putString(SELECTED_LANGUAGE, language)
editor.apply()
}
@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String?): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val configuration = context.resources.configuration
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
return context.createConfigurationContext(configuration)
}
// used for api level < 24
@Suppress("DEPRECATION")
private fun updateResourcesLegacy(context: Context, language: String?): Context {
val locale = Locale(language)
Locale.setDefault(locale)
val resources = context.resources
val configuration = resources.configuration
configuration.locale = locale
resources.updateConfiguration(configuration, resources.displayMetrics)
return context
}
}
Upvotes: 1