赞
踩
安卓的多语言设置配置中strings.xml我就不说怎么弄了,主要说一下后续遇到的坑
上个月接到需求,要给app内添加多语言设置,我心想没啥难的,配置一下strings.xml,加个修改的页面并保存到本地就ok了
然后过了一阵,发现坑真多,然后我写了个工具类,如下:
- /**
- * creator: lt 2019/7/29--16:36 lt.dygzs@qq.com
- * effect : 多语言管理类
- * warning:
- */
- object LanguageManager {
- enum class LocaleEnum(val value: Int) {
- DEFAULT(0),//跟随系统
- CHINESE(1),//简体中文
- TRADITIONAL_CHINESE(2),//繁体中文
- ENGLISH(3),//英文
- }
-
- /**
- * 获取地区对应的enum
- */
- @JvmStatic
- fun getLocaleEnum(locale: Locale): LocaleEnum {
- return when {
- locale.language == Locale.SIMPLIFIED_CHINESE.language -> //中国文字
- if (locale.country == Locale.SIMPLIFIED_CHINESE.country || locale.country.isEmpty()) {
- //简体
- LanguageManager.LocaleEnum.CHINESE
- } else {
- //其他就是繁体文字
- LanguageManager.LocaleEnum.TRADITIONAL_CHINESE
- }
- locale.language == Locale.US.language -> //英文
- LanguageManager.LocaleEnum.ENGLISH
- else -> //其他就是默认的,使用系统语言
- LanguageManager.LocaleEnum.DEFAULT
- }
- }
-
- /**
- * 获取app当前的地区设置
- */
- @JvmStatic
- fun getAppLocale(): Locale {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- BaseApplication.getApp().resources.configuration.locales[0]
- } else {
- BaseApplication.getApp().resources.configuration.locale
- }
- }
-
- /**
- * 获取系统的地区设置
- */
- @JvmStatic
- fun getSystemLocale(): Locale {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- Resources.getSystem().configuration.locales[0]
- } else {
- Resources.getSystem().configuration.locale
- }
- }
-
- /**
- * 获取本地存储的地区设置
- */
- @JvmStatic
- fun getNativeLocale(): Locale {
- return when (SPUtil.readInt("setting", "locale", LanguageManager.LocaleEnum.DEFAULT.value)) {
- LanguageManager.LocaleEnum.CHINESE.value -> Locale.SIMPLIFIED_CHINESE
- LanguageManager.LocaleEnum.TRADITIONAL_CHINESE.value -> Locale.TRADITIONAL_CHINESE
- LanguageManager.LocaleEnum.ENGLISH.value -> Locale.US
- else -> getSystemLocale()
- }
- }
-
- /**
- * 保存地区设置到本地
- */
- @JvmStatic
- fun saveNativeLocale(localeEnum: LocaleEnum) {
- SPUtil.write("setting", "locale", localeEnum.value)
- }
-
- /**
- * 设置语言
- */
- @JvmStatic
- fun setLanguage(context: Context, locale: Locale) {
- val config = context.resources.configuration//获取配置
- config.locale = locale// 根据当前语言来判断,并更改当前语言
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- config.setLocale(locale)
- }// 根据当前语言来判断,并更改当前语言
- context.resources.updateConfiguration(config, context.resources.displayMetrics)//更新配置
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- context.createConfigurationContext(config)
- }//更新配置
- }
-
- /**
- * 初始化有WebView的Activity,必须在onCreate的super下面一行调用
- */
- @JvmStatic
- fun initWebViewActivity(activity: Activity) {
- WebView(activity).destroy()
- setLanguage(activity, getNativeLocale())
- setLanguage(BaseApplication.getApp(), getNativeLocale())
- }
-
- /**
- * 在BaseActivity的attachBaseContext方法中调用
- */
- @JvmStatic
- fun attachBaseContext(context: Context?): ContextWrapper {
- if (context != null)
- setLanguage(context, getNativeLocale())
- return ContextWrapper(context)
- }
-
- }
使用有几个注意点:
Application的onCreate()中调用一次
LanguageManager.setLanguage(this, LanguageManager.getNativeLocale())
然后在BaseActivity中调用如下:在页面初始化的时候设置一下语言(我之前没这样设置的时候华为手机没问题,但是vivo手机很大几率出现语言错乱,所以加上这个)
- override fun attachBaseContext(newBase: Context?) {
- super.attachBaseContext(LanguageManager.attachBaseContext(newBase))
- }
- //根据设置传入用户选中的locale
- LanguageManager.saveNativeLocale(LanguageManager.getLocaleEnum(locale))
- LanguageManager.setLanguage(this, locale)
- LanguageManager.setLanguage(BaseApplication.getApp(), locale)
- recreate();//重新启动当前Activity来改变当前页面的语言
我做完了前面的操作,工具类也封装好了,就在我以为完美的时候,现实再次给了我当头一棒,,,,Android7.0以上的WebView竟然会改变当前语言的设置???
然后查了一下,并参考Android N之后 Webview导致多语言切换失效的问题_android中webview切换多语言刷新问题-CSDN博客
加了个方法,用法如下:
- 在有用到WebView的页面内,在onCreate()内调用如下方法,即可解决这种问题
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- LanguageManager.initWebViewActivity(this)//注意放在super的下面一行
- ............
- }
然后在Application的onCreate中的super.onCreate下调用以下代码
- try {
- new WebView(this).destroy();
- } catch (Exception e) {
- e.printStackTrace();
- }
然后就解决了,emmm方案近乎完美 /捂脸
对Kotlin或KMP感兴趣的同学可以进Q群 101786950
如果这篇文章对您有帮助的话
可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。