注意本文使用的语言的是 Kotlin,如需 Java 请自行转换或在网络自行搜索,本文的 minSDK 为 21
弃用 通常提起 Android 程序更换语言可能会想到 Context
的 getResources().updateConfiguration(configuration, displayMetrics)
,传入设置好 Locale
的 configuration
以及 Context
的 getResources().getDisplayMetrics()
。
然而这个方法在现在已经被标记为 deprecated,这意味着以后的版本可能用不了这个了。
这是官方的信息: ‘updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics)’ is deprecated Deprecated See android.content.Context.createConfigurationContext(Configuration).
那简单了,我们只需要看看 Context.createConfigurationContext(Configuration)
怎么使用就可以了,分析一下,这个方法是返回一个 Context
,那我们只需要重写一下 ContextWrapper
就好了,这样获取到的就是用一个 Context
,保证更换语言成功。
重写 ContextWrapper 这是我写好的 ContextWrapper
,比较简单,需要说明的东西我都写在注释了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 open class ContextWrapper (base: Context?) : ContextWrapper(base) { companion object { @RequiresApi(Build.VERSION_CODES.N) fun wrap (context: Context , newLocale: Locale ?) : ContextWrapper { var mContext = context val res: Resources = mContext.resources val configuration: Configuration = res.configuration mContext = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { configuration.setLocale(newLocale) val localeList = LocaleList(newLocale) LocaleList.setDefault(localeList) configuration.setLocales(localeList) mContext.createConfigurationContext(configuration) } else { configuration.setLocale(newLocale) mContext.createConfigurationContext(configuration) } return ContextWrapper(mContext) } } }
准备好切换工具 我这里准备了一个语言的工具类可以参考一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 object LanguageUtil { fun setLanguage (context: Context , lan: String ) { context.getSharedPreferences("settings" , 0 ).edit { putString("language" , lan) this .commit() } } fun getCheckedItem (context: Context ) : Int = when (context.getSharedPreferences("settings" , 0 ).getString("language" , "cn" )) { "auto" -> 0 "zh-rCN" -> 1 "zh-rTW" -> 2 "en" -> 3 else -> 0 } fun getLocale (context: Context ) : Locale = when (context.getSharedPreferences("settings" , 0 ).getString("language" , "cn" )) { "auto" -> getSysLocale() "zh-rCN" -> Locale("zh" , "CN" ) "zh-rTW" -> Locale("zh" , "TW" ) "en" -> Locale("en" ) else -> getSysLocale() } private fun getSysLocale () : Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { LocaleList.getDefault()[0 ] } else { Locale.getDefault() } }
这里使用了 object
关键字让他变成一个单例类,而且我选择的是把设置的语言信息通过 SharedPreferences
进行存储,这里根据你的实际情况来调整就 OK。
使用 在每一个 Activity
或者你封装好的 BaseActivity
里重写这样的方法即可:
1 2 3 4 5 6 7 8 @RequiresApi(Build.VERSION_CODES.N) override fun attachBaseContext (newBase: Context ?) { val context = newBase?.let { ContextWrapper.wrap(newBase,LanguageUtil.getLocale(newBase)) } super .attachBaseContext(context) }
这样就可以正常的切换语言了