【问题标题】:How to change locale of Activity in Android App programmatically如何以编程方式更改 Android App 中 Activity 的语言环境
【发布时间】:2019-11-29 07:23:08
【问题描述】:

我想在 App 中更改我的语言(或从 SQLite 数据库中保存的变量中设置它)。它正在工作,但它的行为真的很奇怪。如果我打开我的应用程序,它将在onCreate 中更改Locale,但如果我从MainActivity 开始新活动,则新活动(在应用程序启动后是全新的 - 之前从未停止/暂停)使用默认系统语言。如果我退出这个 Activity 并再次启动 Intent,它会突然变成保存的语言。只有第一次启动是加载系统语言。

我有我的 Activity 抽象类,它扩展了我的应用程序中的所有活动。

代码:

lateinit var app: App

override val coroutineContext = Job()

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

class LocaleHelper {

companion object{
    fun changeLocale(context: Context, lang: String){
        val newLocale = Locale(lang)
        Locale.setDefault(newLocale)
        val res = context.resources
        val conf = res.configuration
        conf.setLocale(newLocale)
        res.updateConfiguration(conf, res.displayMetrics)
    }
 }
}

【问题讨论】:

    标签: android kotlin android-activity android-configchanges


    【解决方案1】:

    我认为您需要更改每个 Activity 中的语言,我不确定您想要实现什么,但这就是我可以在我的应用程序中处理本地化的方式

    首先,创建一个类来处理本地化并返回ContextThemeWrapper 以创建具有指定主题的新上下文包装器。

    class Localization(base: Context) : ContextThemeWrapper(base, R.style.AppTheme) {
        companion object {
    
            fun wrap(context: Context, language: String): ContextThemeWrapper {
                var ctx = context
                val config = context.resources.configuration
    
                if (language != "" || language != "en")
                    )
                ) {
                    val locale = Locale(language)
                    Locale.setDefault(locale)
                    //Using setLocale b/c my version is > 17
                    config.setLocale(locale)
                    // Used setLayoutDirection for RTL and LTR
                    config.setLayoutDirection(locale)
                    ctx = context.createConfigurationContext(config)
                }
    
                //Save the selected language in shared Preference,
                //context.putString("my_lang", language)
    
                return Localization(ctx)
            }
      }
    

    然后在需要更改语言时调用 wrap 函数

    wrap(this, "en")
    

    在更改语言并获取当前语言时使用 sharedPreference 在你的活动中。 覆盖 attachBaseContext 并使用当前语言调用wrap 函数

    override fun attachBaseContext(newBase: Context) {
            super.attachBaseContext(
                wrap(
                    newBase,
                    "en"
                )
            )
    
        }
    

    注意:我的建议是使用sharedPreference 进行本地化

    【讨论】:

    • 这是我不想做 ContextWrapper 的原因,因为在 attachbaseContext 中我没有可用的应用程序实例 - 我无法访问其有关语言的数据
    • 也不能使用这个,因为它会在 Firebase Cloud Messaging 上崩溃。此修改后的上下文与 Firebase 服务不兼容
    • 我没有使用 Firebase,但感谢您让我知道
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 2015-07-19
    相关资源
    最近更新 更多