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

前言

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

正文

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

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

/**
 * creator: lt  2019/7/29--16:36    [email protected]
 * 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竟然会改变当前语言的设置???

然后查了一下,并参考https://blog.csdn.net/xunmeng_93/article/details/78632210

加了个方法,用法如下:

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

然后就解决了,emmm方案近乎完美(希望不要被测试打脸) /捂脸

发布了42 篇原创文章 · 获赞 192 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_33505109/article/details/99087615