android - 在 Kotlin 中以编程方式更改语言环境

标签 android kotlin localization

我有一些代码可以在 Java 中以编程方式更改语言环境。但是当我的应用程序迁移到 Kotlin 时,我无法再更改语言环境。

例如,Java 中的这段代码运行良好:

public static final void setAppLocale(String language, Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        Resources resources = activity.getResources();
        Configuration configuration = resources.getConfiguration();
        configuration.setLocale(new Locale(language));
        activity.getApplicationContext().createConfigurationContext(configuration);
    } else {
        Locale locale = new Locale(language);
        Locale.setDefault(locale);
        Configuration config = activity.getResources().getConfiguration();
        config.locale = locale;
        activity.getResources().updateConfiguration(config,
                activity.getResources().getDisplayMetrics());
    }
}

我在 Kotlin 中尝试了很多代码,但没有一个对我有用。这是我最后一次尝试:

fun changeLanguage(context: Context, language : String) {
    val locale = Locale(language)
    Locale.setDefault(locale)

    val config = context.resources.configuration
    config.setLocale(locale)
    context.createConfigurationContext(config)
    context.resources.updateConfiguration(config, context.resources.displayMetrics)
}

如何在 Kotlin 中更改应用程序的本地地址?用 Java 编写的旧代码在 Kotlin 应用程序中不起作用。

最佳答案

假设创建一个 Context 辅助类

class ApplicationLanguageHelper(base: Context) : ContextThemeWrapper(base, R.style.AppTheme) {
companion object {

    fun wrap(context: Context, language: String): ContextThemeWrapper {
        var context = context
        val config = context.resources.configuration
        if (language != "") {
            val locale = Locale(language)
            Locale.setDefault(locale)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                setSystemLocale(config, locale)
            } else {
                setSystemLocaleLegacy(config, locale)
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                config.setLayoutDirection(locale)
                context = context.createConfigurationContext(config)
            } else {
                context.resources.updateConfiguration(config, context.resources.displayMetrics)
            }
        }
        return ApplicationLanguageHelper(context)
    }

    @SuppressWarnings("deprecation")
    fun setSystemLocaleLegacy(config: Configuration, locale: Locale) {
        config.locale = locale
    }

    @TargetApi(Build.VERSION_CODES.N)
    fun setSystemLocale(config: Configuration, locale: Locale) {
        config.setLocale(locale)
    }
}

并且在您的 Activity 中您可以覆盖 attachBaseContext

    override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(ApplicationLanguageHelper.wrap(newBase!!, "fa"))
}

要更改语言,您可以使用 Spinner 或任何其他首选方式,调用以下方法 OnClick

   private fun changeApplicationLanguage(language:String){
    val sharedPreferencesEditor = sharedPreferences.edit()
    when (language) {
        ENGLISH -> sharedPreferencesEditor?.putString(SELECTED_LANGUAGE, ENGLISH)
        PERSIAN -> sharedPreferencesEditor?.putString(SELECTED_LANGUAGE, PERSIAN)
        PASHTO -> sharedPreferencesEditor?.putString(SELECTED_LANGUAGE, PASHTO)
    }
    sharedPreferencesEditor.putBoolean(LANGUAGE_IS_SELECTED, true)
    sharedPreferencesEditor?.apply()
    recreate()
}

确保您定义了 sharedPreferences 以及 SELECTED_LANGUAGEENGLISH 等,consts

const val SELECTED_LANGUAGE = "language"
const val ENGLISH = "en"
const val PERSIAN = "fa"
const val PASHTO = "ps"

 private lateinit var sharedPreferences: SharedPreferences

并在 setContent 之后在 onCreate 方法中初始化 sharedPreferences

sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this@Your_Activity_Name)

还可以通过添加以下代码来覆盖基本上下文

 // Overwrite the context
override fun attachBaseContext(newBase: Context?) {
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(newBase)
    val lang = sharedPreferences.getString(SELECTED_LANGUAGE, "en")
    super.attachBaseContext(ApplicationLanguageHelper.wrap(newBase!!, lang!!))
}

我确信这种方法不是最佳解决方案,但是,这可能会有所帮助

关于android - 在 Kotlin 中以编程方式更改语言环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50785840/

相关文章:

java - 从 Android 中的 fragment 管理工具栏中的后退按钮

android - bottomNavigationView 内边距或边距上的徽章

java - 如何使用 Jackson 和 spring-boot 将简单的 Kotlin 数据类映射到 json 或从 json 映射

ios - 应用商店本地化描述未正确显示

两种不同语言的 iOS 应用程序,无需本地化

java - Kotlin 转换期间删除了 Setter/Getter

android - 获取仅一个字符的货币符号(例如$,₹等)(语言环境无关紧要)

java - Android 应用程序位图的替代方案

android - 返回类型 'getItem' 不是被覆盖成员的返回类型的子类型

java - 如何更改 Struts2 中的默认日期格式?