赞
踩
本文介绍强制将App语言指定为中文。也就是不管当前系统是英文环境还是其他语言环境,都将App的语言指定为中文。简单直白废字数点,就是不管是什么语言环境,启动App看到都是中文。
备注:若需动态切换语言,原理和这个差不多。
/** * @Creator City * @Date 2020/7/24 * @Description:强制将App语言指定为中文 * @params:activity,当前Activity * 忽略文中的try...catch...(项目即将上线时发现的问题,来不及测试,所以.....) */ fun forceChinese(activity: FragmentActivity) { fun action(res: Resources) { try { val config = res.configuration var local: Locale? = null if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 可看Android手机设置->语言与输入法->语言。该页面是一个语言列表(localList) // 就是代码这里的localList val localList = config.locales if (!localList.isEmpty) { // 虽然localList是一个列表,但是生效的是第一个local,你调试一下就知道了 local = localList.get(0) } } else { // 低版本sdk就只有一个local,没有语言列表 local = config.locale } local?.let { //中文环境(包括简体中文,繁体中文),若要指定地区,还要加上Locale.CHINESE.country val zh = Locale.CHINESE.language if (!it.language.contains(zh)) { // 打开注释,调试用,看看哪些页面会偷偷更改Local(可以打开一个内嵌WebView的Activity看看) // Log.d("City_Language", res.toString()) config.setLocale(Locale.CHINESE) // createConfigurationContext(config) // 推荐用该方法,但是不生效,原因未知 res.updateConfiguration(config, res.displayMetrics) } } } catch (e: Exception) { // empty } } try { // ???为什么这里执行两次action action(BaseApplication.getApp().resources) action(activity.resources) } catch (e: Exception) { // empty } }
我们一般在项目中有个Activity基类,我这里是BaseActivity。如果你项目里没有用到这样子的基类,建议你百度一下“Android BaseActivity”。
备注:最近在学设计模式,这里的Activity基类也就是BaseActivity是“模板方法模式”哦。
/** * @Creator City * @Date 2020/7/26 * @Description: * BaseLanguageActivity继承BaseActivity,具体Activity如PageActivity继承BaseLanguageActivity。 * BaseLanguageActivity就只处理Language方面的,算不算六大原则之一的“单一职责原则”? */ abstract class BaseLanguageActivity : BaseActivity(){ /** * 这个方法会在onCreate()之前调用 * 为什么这里要调用?主要是第一个页面,后面的onResume,onConfiguration两个方法对于第一页不适用 */ override fun attachBaseContext(newBase: Context?) { super.attachBaseContext(newBase) forceLanguage(this) } /** * 每次onResume都调用一次 * 为什么? * 如果我们在PageA页面调用了一次,跳转到PageB页面更改了Local,那再次回到PageA页面时再调用一次,防止意外 * 什么意外?实战来解释 * 如果PageB页面内嵌了一个WebView。WebView内部会更改Local,这个是我猜的,我没看源码,当我打开PageB时 * 发现方法forceChinese中的Log.d("City_Language", res.toString())有打印,说明我们在PageA页面更 * 改为中文Local后,到PageB页面后Local发生了变化。 */ override fun onResume() { super.onResume() forceLanguage(this) } /** * 系统的配置信息发生改变时,再调用一次forceLanguage */ override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) forceLanguage(this) } }
你是否发现你的App内部有多个Resource对象?我们先看看如何获取Resource对象:
1:getApplicationContext().getResources() // 在工具类中需要加载String时会采用ApplicationContext
2:getResources() // 在Activity里,直接获取
当我们打印这两个Resource时,发现这两个地址并不同。因此一个App内有多少个Resource对象,并且在不同场景下要用到这些Resource时,就要分别设置Resource。像方法forceChinese()中那样。否则会出现“部分页面切换成功,部分页面切换失败。或者同一个页面出现多种语言的情况哦~~~”。
我是在模拟器Android 9、Android 10且是英文环境上进行调试的。
如下图,localList,生效的是localList.get(0),也就是当前Phone语言环境是英文
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。