前言
在开发一个客户的产品,需要在美国展会上使用,所以就需要多语言切换的app,临时抱佛脚,百度了一下发现都在用 context.getResources().updateConfiguration 这个已经在 API 25的时候 deprecated 的接口。
解决方法
建立其他语言文件
在res文件夹中创建文件夹 values-en, 再在其中创建 strings.xml 文件,这时候会在文件左侧显示图标为一面国旗
然后将中文里面有的字符串常量一股脑的全部翻译过来即可。
帮助类
我们需要加入这个帮助类文件 LanguageContextWrapper.kt
import android.content.ContextWrapper
import android.os.Build
import android.annotation.TargetApi
import java.util.*
@Suppress("DEPRECATION")
fun ContextWrapper.wrap(language: String): ContextWrapper {
val config = baseContext.resources.configuration
val sysLocale: Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.getSystemLocale()
} else {
this.getSystemLocaleLegacy()
}
if (language.isNotEmpty() && sysLocale.language != language) {
val locale = Locale(language)
Locale.setDefault(locale)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
this.setSystemLocale(locale)
} else {
this.setSystemLocaleLegacy(locale)
}
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
val context = baseContext.createConfigurationContext(config)
ContextWrapper(context)
} else {
baseContext.resources.updateConfiguration(config, baseContext.resources.displayMetrics)
ContextWrapper(baseContext)
}
}
@Suppress("DEPRECATION")
fun ContextWrapper.getSystemLocaleLegacy(): Locale {
val config = baseContext.resources.configuration
return config.locale
}
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.getSystemLocale(): Locale {
val config = baseContext.resources.configuration
return config.locales[0]
}
@Suppress("DEPRECATION")
fun ContextWrapper.setSystemLocaleLegacy(locale: Locale) {
val config = baseContext.resources.configuration
config.locale = locale
}
@TargetApi(Build.VERSION_CODES.N)
fun ContextWrapper.setSystemLocale(locale: Locale) {
val config = baseContext.resources.configuration
config.setLocale(locale)
}
语言记录存储
使用 SharedPreferences 存储语言选择
class SpfUtils(context: Context) {
private val mSpf = context.getSharedPreferences("config_data", Context.MODE_PRIVATE)
companion object {
@Volatile
private var INSTANCE: SpfUtils? = null
@JvmStatic
fun getInstance(context: Context) : SpfUtils {
val temp = INSTANCE
if (null != temp) {
return temp
}
synchronized(this) {
val instance = SpfUtils(context)
INSTANCE = instance
return instance
}
}
private const val SPF_LANGUAGE = "language"
}
fun getSpf() : SharedPreferences {
return mSpf
}
fun getLanguage() : String = mSpf.getString(SPF_LANGUAGE, Locale.ENGLISH.language)?: Locale.ENGLISH.language
fun setLanguage(language: String) {
mSpf.edit().putString(SPF_LANGUAGE, language).apply()
}
}
切换语言
在你的每个Activity中加入以下代码(或者在你的Base类里添加)
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(ContextWrapper(newBase).wrap(SpfUtils.getInstance(newBase).getLanguage()))
}
然后,当你修改了语言选择并存到 SharedPreferences,重新启动页面就会改变语言了。