前言
安卓的多语言设置配置中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)
}
}
使用有几个注意点:
1.初始化地点:
Application的onCreate()中调用一次
LanguageManager.setLanguage(this, LanguageManager.getNativeLocale())
然后在BaseActivity中调用如下:在页面初始化的时候设置一下语言(我之前没这样设置的时候华为手机没问题,但是vivo手机很大几率出现语言错乱,所以加上这个)
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(LanguageManager.attachBaseContext(newBase))
}
2.更改语言设置:
//根据设置传入用户选中的locale
LanguageManager.saveNativeLocale(LanguageManager.getLocaleEnum(locale))
LanguageManager.setLanguage(this, locale)
LanguageManager.setLanguage(BaseApplication.getApp(), locale)
recreate();//重新启动当前Activity来改变当前页面的语言
3.WebView的坑
我做完了前面的操作,工具类也封装好了,就在我以为完美的时候,现实再次给了我当头一棒,,,,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
如果这篇文章对您有帮助的话
可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)