这个问题也让我有些头疼,特别是因为谷歌认为这不是他们这边的错误。但是,这绝对不是应用程序中所期望的行为,即仅在打开 WebView 时语言就会更改。
我们的解决方案不依赖硬编码语言,适用于 Android 7+。首先,将此代码添加到您的应用程序 build.gradle 文件中:
android {
defaultConfig {
...
resConfigs rootProject.ext.available_languages
buildConfigField "String[]", "AVAILABLE_LANGUAGES", "{\"${rootProject.ext.available_languages.join("\",\"")}\"}"
}
}
并将以下代码添加到您的根 build.gradle:
ext {
available_languages = ["en", "de"]
}
这两个代码块定义了可用strings.xml
文件的列表并将列表放入BuildConfig.AVAILABLE_LANGUAGES
字段中。
现在,我们可以BaseActivity
使用以下代码定义 a ,所有活动都应从其扩展:
abstract class BaseActivity : AppCompatActivity() {
override fun attachBaseContext(newBase: Context) {
val locale = getFirstAvailableLocale(newBase)
val context = createContextWithLocale(locale, newBase)
super.attachBaseContext(context)
}
private fun getFirstAvailableLocale(context: Context): Locale {
val availableLanguages = BuildConfig.AVAILABLE_LANGUAGES // Gets list of available languages defined in the build.gradle file
val locales = context.resources.configuration.locales
for (i in 0..locales.size()) {
if (locales[i].language in availableLanguages) {
return locales[i]
}
}
return locales[0]
}
@Suppress("DEPRECATION")
private fun createContextWithLocale(locale: Locale, baseContext: Context): Context {
val resources = baseContext.resources
val configuration = resources.configuration
val localeList = LocaleList(locale)
LocaleList.setDefault(localeList)
configuration.setLocales(localeList)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
baseContext.createConfigurationContext(configuration)
} else {
resources.updateConfiguration(configuration, resources.displayMetrics)
baseContext
}
}
}
您甚至可以扩展此解决方案以支持不同的区域,但是您必须将字符串从 resConfigs 拆分为语言和区域,因为Locale
该类无法正确识别语言标签(例如,需要在 resConfigs 中定义 de-rDE,但Locale
会成为de_DE)