首页 > 解决方案 > Android:如何以编程方式更改应用程序语言?

问题描述

我想以编程方式更改我的应用程序语言。我有一些适用于旧手机(Android 6)的代码,但它不适用于 Android 8 和 Android 9。任何适用于应用语言更改的解决方案?调用 setLocal 后,我在 Activity 中调用 recreate()。字符串仍然没有变化。

在我MainActivity的扩展BaseActivity中,onCreate()如果我调用Locale.getDefault().language它,它会返回正确的语言代码,但字符串仍然是英语,这是默认的string.xml

fun setLocale(context: Context, language: String?): Context {
    app.setLanguage(language)

    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        updateResources(context, language)
    } else updateResourcesLegacy(
        context,
        language
    )

}

@TargetApi(Build.VERSION_CODES.N)
private fun updateResources(context: Context, language: String?): Context {
    val locale =
    if (language == null){
        Locale(Locale.getDefault().language)
    } else {
        Locale(language)
    }

    Locale.setDefault(locale)
    val configuration = context.resources.configuration
    configuration.setLocale(locale)

    return context.createConfigurationContext(configuration)
}

@Suppress("DEPRECATION")
private fun updateResourcesLegacy(context: Context, language: String?): Context {
    val locale =
        if (language == null){
            Locale(Locale.getDefault().language)
        } else {
            Locale(language)
        }

    Locale.setDefault(locale)
    val resources = context.resources

    val configuration = resources.configuration
    configuration.locale = locale

    resources.updateConfiguration(configuration, resources.displayMetrics)

    return context
}

更新:我使用了以下两种解决方案的组合,但仍然没有成功。我BaseActivity上课的时间因我的所有活动而延伸。在那里我调用changeLocale了类似于 LocaleHelper 的函数。app.getSavedLanguage()在我的sharedPrefs. 此代码会根据用户在应用程序中选择的语言被覆盖。App 是使用共享首选项的应用程序类。

override fun onCreate(si: Bundle?) {
        super.onCreate(si)
        app = application as App
        changeLocale(this, app.getSavedLanguage())
    }

    open fun changeLocale(context: Context, lang: String) {
        val newLocale = Locale(lang)
        Locale.setDefault(newLocale)

        val res: Resources = context.resources
        val conf: Configuration = res.configuration

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            conf.apply {
                setLocale(newLocale)
                setLayoutDirection(newLocale)
            }

            context.createConfigurationContext(conf)
        } else {
            conf.apply {
                locale = newLocale
                setLayoutDirection(newLocale)
            }

            res.updateConfiguration(conf, res.displayMetrics)
        }
    }

标签: androidlocale

解决方案


onCreate()之前可以在 MainActivity 中使用这个配置setContentView()

@Override
protected void onCreate(Bundle savedInstanceState) {
    SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String appLang = sharedPreferences.getString("appLanguage", Locale.getDefault().getLanguage());

    Locale myLocale = new Locale(appLang);
    Resources res = getResources();
    DisplayMetrics dm = res.getDisplayMetrics();
    Configuration conf = res.getConfiguration();
    conf.locale = myLocale;
    Locale.setDefault(myLocale);
    conf.setLayoutDirection(myLocale);
    res.updateConfiguration(conf, dm);

    setContentView(R.layout.activity_main);
}

推荐阅读