美文网首页
Android多语言不重启以及踩坑日记

Android多语言不重启以及踩坑日记

作者: Kenny_e364 | 来源:发表于2020-01-18 13:54 被阅读0次

1、不重启切换语言

在做完updateConfiguration后,需要做的操作就是将程序退出到首页,并再次对resources执行update操作

private fun onLanguageChange() {
        val language = I18NUtils.getCurrentLanguage(this).replace("-", "_")
        val resources = applicationContext.resources
        val dm = resources.displayMetrics
        val mConfig = resources.configuration
        val locale = LanguageManager.getInstance(this).getLanguageLocal(language)
        mConfig.locale = locale
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            val localeList = LocaleList(locale)
            LocaleList.setDefault(localeList)
            mConfig.locales = localeList
            this.applicationContext.createConfigurationContext(mConfig)
            Locale.setDefault(locale)
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            mConfig.setLocale(locale)
        }
        resources.updateConfiguration(mConfig, dm)
    }

然后对首页Activity执行recreate操作即可。

2、个别设备简繁体获取均为zh_CN

有一部分机型,获取繁简体时,返回的都是zh_CN,在繁简体切换时,会出现繁体显示简体,简体显示繁体的问题,原因是系统是根据Locale.java中的script来进行判断的。简体中文为"Hans"繁体中文为"Hant",获取的Locale分别为zh_CN_#Hanszh_CN_#Hant
知道了这个情况后,却发现,另一个尴尬的问题,Locale的所有构造方法张,并没有script参数的传递方法,且scriptBaseLocale中的一个私有final常量....

但是惊喜的是,Locale中有一个内部类Builder

    public static final class Builder {
        private final InternalLocaleBuilder localeBuilder;

        public Builder() {
            localeBuilder = new InternalLocaleBuilder();
        }

        ......

        public Builder setLocale(Locale locale) {
            try {
                localeBuilder.setLocale(locale.baseLocale, locale.localeExtensions);
            } catch (LocaleSyntaxException e) {
                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
            }
            return this;
        }

        public Builder setScript(String script) {
            try {
                localeBuilder.setScript(script);
            } catch (LocaleSyntaxException e) {
                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
            }
            return this;
        }

        ......

        public Locale build() {
            BaseLocale baseloc = localeBuilder.getBaseLocale();
            LocaleExtensions extensions = localeBuilder.getLocaleExtensions();
            if (extensions == null && baseloc.getVariant().length() > 0) {
                extensions = getCompatibilityExtensions(baseloc.getLanguage(), baseloc.getScript(),
                        baseloc.getRegion(), baseloc.getVariant());
            }
            return Locale.getInstance(baseloc, extensions);
        }
    }

有了这个Builder就可以完美的定义Local

val cofig = resources.configuration
var locale = Locale(split[0], split[1].toUpperCase(Locale.getDefault()))
val builder = Locale.Builder()
builder.setLocale(locale)
if (split[0] == "zh") {
    builder.setScript(
        if (split[1].equals("cn", ignoreCase = true)) {
            "Hans"
        } else {
            "Hant"
        }
    )
}
locale = builder.build()
cofig.setLocale(locale)
val con = baseContext.createConfigurationContext(cofig)

\color{black}{\Large\mathbf{ }}
\color{black}{\Large\mathbf{完}}

相关文章

网友评论

      本文标题:Android多语言不重启以及踩坑日记

      本文链接:https://www.haomeiwen.com/subject/slpkzctx.html