在onCreate

时间:2019-07-12 10:21:11

标签: android sharedpreferences locale

我尝试在应用中设置区域设置,首先运行它即可。但是,在onCreate()(旋转)将重置为默认语言后,重置后我无法在应用中更改语言。

我使用SharePreference保存区域设置值

PrefUtils.java从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设置区域设置,我输入了onCreate和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());
    }

1 个答案:

答案 0 :(得分:0)

在活动类中,您应该覆盖attachBaseContext(base : Context)

创建一个抽象类BaseActivity并将其扩展到MainActivity上。

通过这样做,您不必在每个活动类中都写onAttachBaseContext(),而应该扩展BaseActivity而不是AppCompatActivity

class BaseActivity : AppCompatActivity {

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(LocaleHelper.onAttach(base))
    }
}

要保留语言设置,您还应该在Application类中覆盖attachBaseContext(base:Context)

class App : Application() {

   override fun attachBaseContext(base: Context) {
        super.attachBaseContext(LocaleHelper.onAttach(base, LocaleHelper.LANG_EN))
    }
}

如果您需要本地化的帮助程序类,这里是一个。该代码在Kotlin中,但是我想您会明白的。

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
    }
}