美文网首页
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