【问题标题】:Not able to change language locale in Kotlin无法更改 Kotlin 中的语言区域设置
【发布时间】:2019-11-18 05:34:24
【问题描述】:

我有 2 个字符串文件“en”和“es”。当我在语言环境管理器类中更改语言环境时,它会成功保存新的语言环境,但不会反映刷新活动的更改。

MyApplication.kt

open class MyApplication : Application() {

    init {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(LocaleManagerMew.setLocale(base))
       // MultiDex.install(base)
    }

    override fun onCreate() {
        super.onCreate()

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        LocaleManagerMew.setLocale(this)
        Log.d("app", "onConfigurationChanged: " + newConfig.locale.getLanguage())
    }
}

LocaleManagerNew.kt

object LocaleManagerMew {

    val SELECTED_LANGUAGE = "MEW_CURRENT_-- USER_LANGUAGE"
    var mSharedPreference: SharedPref? = null

    var mEnglishFlag = "en"
    var mSpanishFlag = "es"

    fun setLocale(context: Context?): Context {
        return updateResources(context!!, getCurrentLanguage(context)!!)
    }

    inline fun setNewLocale(context: Context, language: String) {

        persistLanguagePreference(context, language)
        updateResources(context, language)
    }

    inline fun getCurrentLanguage(context: Context?): String? {

        var mCurrentLanguage: String?

        if (mSharedPreference == null)
            mSharedPreference = SharedPref(context!!)

        mCurrentLanguage = mSharedPreference!!.getSavedLang()

        return mCurrentLanguage
    }

    fun persistLanguagePreference(context: Context, language: String) {
        if (mSharedPreference == null)
            mSharedPreference = SharedPref(context!!)

        mSharedPreference!!.setSavedLang(language)

    }

    fun updateResources(context: Context, language: String): Context {

        var contextFun = context

        var locale = Locale(language)
        Locale.setDefault(locale)

        var resources = context.resources
        var configuration = Configuration(resources.configuration)

        if (Build.VERSION.SDK_INT >= 17) {
            configuration.setLocale(locale)
            contextFun = context.createConfigurationContext(configuration)
        } else {
            configuration.locale = locale
            resources.updateConfiguration(configuration, resources.getDisplayMetrics())
        }
        return contextFun
    }
}

BaseActivity.kt

override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(LocaleManagerMew.setLocale(base))
    }

MainActivity.kt

 R.id.spanishCL ->  {
                sp.setSavedLang("es")
                var mCurrentLanguage = LocaleManagerMew.getCurrentLanguage(this@MainActivity.applicationContext)
                LocaleManagerMew.setNewLocale(this@MainActivity, LocaleManagerMew.mSpanishFlag)
               mContext?.recreate()

            }

这是将英语语言环境更改为西班牙语的 onClick 方法调用。重新创建活动后,新的语言环境更改不会反映

【问题讨论】:

    标签: android kotlin locale


    【解决方案1】:

    尝试使用以下代码从 每个 Activity

    的 attachBaseContext 更新语言
        fun setLanguage(context: Context, language: String): ContextWrapper {
            var mContext = context
    
            val localeLang = language.split("_".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            val locale: Locale
            if (localeLang.size > 1)
                locale = Locale(localeLang[0], localeLang[1])
            else
                locale = Locale(localeLang[0])
    
            val res = mContext.resources
            val configuration = res.configuration
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                val localeList = LocaleList(locale)
                LocaleList.setDefault(localeList)
                configuration.locales = localeList
                mContext = mContext.createConfigurationContext(configuration)
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                configuration.setLocale(locale)
                mContext = mContext.createConfigurationContext(configuration)
            } else {
                configuration.locale = locale
                res.updateConfiguration(configuration, res.getDisplayMetrics())
            }
    
            return ContextWrapper(mContext)
        }
    

    以及Activity类的attachBaseContext中的实现

    //    For Language Changing
    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase?.let {
            Common.setLanguage(
                it,
                PreferenceManager.getPref<String>(Constants.LANGUAGE_PREFERENCE).toString()
            )
        })
    }
    

    这就是我如何重新启动片段中的活动

    Handler().post {
                val intent = activity?.intent
                intent?.flags =
                    Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or
                            Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NO_ANIMATION
                activity?.overridePendingTransition(0, 0)
                activity?.finish()
    
                activity?.overridePendingTransition(0, 0)
                startActivity(intent)
            }
    

    【讨论】:

    • 你试过了吗?因为您试图在 val 中分配一个值,即 configuration.locales
    • 是的,我已经在我的代码中尝试并实现了这一点,它对我来说工作正常
    • 但我收到错误,即无法重新分配 val 即 configuration.locales
    • 这很奇怪,因为我没有在我的代码中抛出任何错误
    • @kartikavij 检查更新的答案以进行实施。我已经在 Common 类中添加了这个函数
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多