当前位置:   article > 正文

安卓多语言设置,深渊巨坑,适配7.0以上,并且解决因WebView产生的问题_android webview多语言

android webview多语言

前言

安卓的多语言设置配置中strings.xml我就不说怎么弄了,主要说一下后续遇到的坑

正文

上个月接到需求,要给app内添加多语言设置,我心想没啥难的,配置一下strings.xml,加个修改的页面并保存到本地就ok了

然后过了一阵,发现坑真多,然后我写了个工具类,如下:

  1. /**
  2. * creator: lt 2019/7/29--16:36 lt.dygzs@qq.com
  3. * effect : 多语言管理类
  4. * warning:
  5. */
  6. object LanguageManager {
  7. enum class LocaleEnum(val value: Int) {
  8. DEFAULT(0),//跟随系统
  9. CHINESE(1),//简体中文
  10. TRADITIONAL_CHINESE(2),//繁体中文
  11. ENGLISH(3),//英文
  12. }
  13. /**
  14. * 获取地区对应的enum
  15. */
  16. @JvmStatic
  17. fun getLocaleEnum(locale: Locale): LocaleEnum {
  18. return when {
  19. locale.language == Locale.SIMPLIFIED_CHINESE.language -> //中国文字
  20. if (locale.country == Locale.SIMPLIFIED_CHINESE.country || locale.country.isEmpty()) {
  21. //简体
  22. LanguageManager.LocaleEnum.CHINESE
  23. } else {
  24. //其他就是繁体文字
  25. LanguageManager.LocaleEnum.TRADITIONAL_CHINESE
  26. }
  27. locale.language == Locale.US.language -> //英文
  28. LanguageManager.LocaleEnum.ENGLISH
  29. else -> //其他就是默认的,使用系统语言
  30. LanguageManager.LocaleEnum.DEFAULT
  31. }
  32. }
  33. /**
  34. * 获取app当前的地区设置
  35. */
  36. @JvmStatic
  37. fun getAppLocale(): Locale {
  38. return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  39. BaseApplication.getApp().resources.configuration.locales[0]
  40. } else {
  41. BaseApplication.getApp().resources.configuration.locale
  42. }
  43. }
  44. /**
  45. * 获取系统的地区设置
  46. */
  47. @JvmStatic
  48. fun getSystemLocale(): Locale {
  49. return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  50. Resources.getSystem().configuration.locales[0]
  51. } else {
  52. Resources.getSystem().configuration.locale
  53. }
  54. }
  55. /**
  56. * 获取本地存储的地区设置
  57. */
  58. @JvmStatic
  59. fun getNativeLocale(): Locale {
  60. return when (SPUtil.readInt("setting", "locale", LanguageManager.LocaleEnum.DEFAULT.value)) {
  61. LanguageManager.LocaleEnum.CHINESE.value -> Locale.SIMPLIFIED_CHINESE
  62. LanguageManager.LocaleEnum.TRADITIONAL_CHINESE.value -> Locale.TRADITIONAL_CHINESE
  63. LanguageManager.LocaleEnum.ENGLISH.value -> Locale.US
  64. else -> getSystemLocale()
  65. }
  66. }
  67. /**
  68. * 保存地区设置到本地
  69. */
  70. @JvmStatic
  71. fun saveNativeLocale(localeEnum: LocaleEnum) {
  72. SPUtil.write("setting", "locale", localeEnum.value)
  73. }
  74. /**
  75. * 设置语言
  76. */
  77. @JvmStatic
  78. fun setLanguage(context: Context, locale: Locale) {
  79. val config = context.resources.configuration//获取配置
  80. config.locale = locale// 根据当前语言来判断,并更改当前语言
  81. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  82. config.setLocale(locale)
  83. }// 根据当前语言来判断,并更改当前语言
  84. context.resources.updateConfiguration(config, context.resources.displayMetrics)//更新配置
  85. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  86. context.createConfigurationContext(config)
  87. }//更新配置
  88. }
  89. /**
  90. * 初始化有WebView的Activity,必须在onCreate的super下面一行调用
  91. */
  92. @JvmStatic
  93. fun initWebViewActivity(activity: Activity) {
  94. WebView(activity).destroy()
  95. setLanguage(activity, getNativeLocale())
  96. setLanguage(BaseApplication.getApp(), getNativeLocale())
  97. }
  98. /**
  99. * 在BaseActivity的attachBaseContext方法中调用
  100. */
  101. @JvmStatic
  102. fun attachBaseContext(context: Context?): ContextWrapper {
  103. if (context != null)
  104. setLanguage(context, getNativeLocale())
  105. return ContextWrapper(context)
  106. }
  107. }

使用有几个注意点:

1.初始化地点:

Application的onCreate()中调用一次

LanguageManager.setLanguage(this, LanguageManager.getNativeLocale())

然后在BaseActivity中调用如下:在页面初始化的时候设置一下语言(我之前没这样设置的时候华为手机没问题,但是vivo手机很大几率出现语言错乱,所以加上这个)

  1. override fun attachBaseContext(newBase: Context?) {
  2. super.attachBaseContext(LanguageManager.attachBaseContext(newBase))
  3. }

2.更改语言设置:

  1. //根据设置传入用户选中的locale
  2. LanguageManager.saveNativeLocale(LanguageManager.getLocaleEnum(locale))
  3. LanguageManager.setLanguage(this, locale)
  4. LanguageManager.setLanguage(BaseApplication.getApp(), locale)
  5. recreate();//重新启动当前Activity来改变当前页面的语言

3.WebView的坑

我做完了前面的操作,工具类也封装好了,就在我以为完美的时候,现实再次给了我当头一棒,,,,Android7.0以上的WebView竟然会改变当前语言的设置???

然后查了一下,并参考Android N之后 Webview导致多语言切换失效的问题_android中webview切换多语言刷新问题-CSDN博客

加了个方法,用法如下:

  1. 在有用到WebView的页面内,在onCreate()内调用如下方法,即可解决这种问题
  2. override fun onCreate(savedInstanceState: Bundle?) {
  3. super.onCreate(savedInstanceState)
  4. LanguageManager.initWebViewActivity(this)//注意放在super的下面一行
  5. ............
  6. }

 然后在Application的onCreate中的super.onCreate下调用以下代码

  1. try {
  2. new WebView(this).destroy();
  3. } catch (Exception e) {
  4. e.printStackTrace();
  5. }

然后就解决了,emmm方案近乎完美 /捂脸

对Kotlin或KMP感兴趣的同学可以进Q群 101786950

如果这篇文章对您有帮助的话

可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/196540
推荐阅读