美文网首页技术Android开发经验谈Android开发
Android-国际化(多语言)切换详解及实例

Android-国际化(多语言)切换详解及实例

作者: 秦子帅 | 来源:发表于2017-10-17 09:30 被阅读291次

    internationalization(国际化)简称 i18n,因为在i和n之间还有18个字符,localization(本地化),简称L10n。

    一.原理:

    Android中实现国际化相对来说还是简单的,因为Android有很独特的资源管理方式。代码可以不和资源发生关系,我们通常通过 R 文件提供的索引来间接的引用某一个资源。

    把显示的字符串都转换成文件资源,再用代码代码提取,也就是把字符串存储在对应的values目录下。


    二.实现步骤:

    国际化切换可以手动国际化,也可以一键国际化。

    1.手动国际化
    为支持多国语言,在res/中创建一个额外的values目录以连字符和ISO国家代码结尾命名,比如values-es/是为语言代码为"es"的区域设置的简单的资源文件的目录。Android会在运行时根据设备的区域设置,加载相应的资源。
    以中英文切换为例:
    如果默认是中文就不用建立相应的values文件了,因为系统找不到对应的资源直接会走默认的。
    (1).首先建立一个values资源文件values-en/放进对应的strings.xml。


    添加不同区域语言的字符串值到相应的文件就可以了。

    (2).UI显示字符串用代码提取:
    生成对应的string文件不用每个都改,这样很麻烦,教大家一个简单方法如下:

    这样直接就生成了string.xml,直接去改相应的字符串就好了。

    2.一键国际化
    如果需要很多语言的时候,手动的切换很麻烦。这时需要用到Android Studio插件:AndroidLocalizationer,它可以实现一键国际化。
    使用方法:
    (1).下载AndroidLocalizationer插件
    下载地址:
    https://github.com/westlinkin/AndroidLocalizationer
    (2).集成到Android studio中。


    集成成功之后重启。
    (3).使用


    根据你的需要来选择对应的语言
    结果如下:

    附加:这个插件还是有些不稳定的地方,有的Android Studio版本是不支持此插件的。


    二.国际化实现实例


    1.配置资源文件,这个在前面已经讲过了。
    2.封装一个ContextWrapper类
    ContextWrapper构造函数中必须包含一个真正的Context引用,同时ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。
    public class MyContextWrapper extends ContextWrapper {
    
        public MyContextWrapper(Context base) {
            super(base);
        }
    
        @SuppressWarnings("deprecation")
        public static ContextWrapper wrap(Context context, String language) {
            Configuration config = context.getResources().getConfiguration();
            Locale sysLocale = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                sysLocale = getSystemLocale(config);
            } else {
                sysLocale = getSystemLocaleLegacy(config);
            }
            if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
                Locale locale = new Locale(language);
                Locale.setDefault(locale);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    setSystemLocale(config, locale);
                } else {
                    setSystemLocaleLegacy(config, locale);
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                    context = context.createConfigurationContext(config);
                } else {
                    context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
                }
            }
            return new MyContextWrapper(context);
        }
    
        @SuppressWarnings("deprecation")
        public static Locale getSystemLocaleLegacy(Configuration config){
            return config.locale;
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        public static Locale getSystemLocale(Configuration config){
            return config.getLocales().get(0);
        }
    
        @SuppressWarnings("deprecation")
        public static void setSystemLocaleLegacy(Configuration config, Locale locale){
            config.locale = locale;
        }
    
        @TargetApi(Build.VERSION_CODES.N)
        public static void setSystemLocale(Configuration config, Locale locale){
            config.setLocale(locale);
        }
    }
    

    3.attachBaseContext实现

    @Override
    protected void attachBaseContext(Context newBase) {
        //Public.Language 为 对应的资源格式后缀,比如"zh"      "
        super.attachBaseContext(MyContextWrapper.wrap(newBase, Public.Language));
    }
    

    如果想要整个APP都实现国际化,直接把attachBaseContext写在封装好的BaseActivity里。
    4.调用

    //动态改变后缀名,可以存在本地数据中,方法比较多就不细说了。Public.Language="zh";
    recreate();
    

    其中recreate();是Android3.0以后引入的。

    希望大家支持下我的公众号:

    相关文章

      网友评论

      • 37度开水:这个在安卓6.0系统下不管用吧?测过吗?
        秦子帅:@37度开水 已经不管用了。只能手动
      • 猿ape:学习到了

      本文标题:Android-国际化(多语言)切换详解及实例

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