语言国际化知识点梳理

523 阅读4分钟

语言国际化的引入

之前刚开始做开发的时候,前辈们总和我们说,我们的文字最好是写在strings.xml中。之所以要写在这个文件中,是因为写在一个地方,有利于项目的维护。还有一个原因就是方便以后产品说要做国际化的功能。

语言国际化的需求

这个功能的需求,基本上大相径庭,没有什么大的不同。那最基本的需求有哪些呢?
1、就是能在app中有一个能选择语言的入口,用户选择什么语言,整个app的文字就显示什么语言。
2、当用户选择跟随系统时,用户在系统设置中选择什么语言,那app就显示什么语言。
有时候会想,做国际化的目的是什么呢?
你想想,如果有一个app是美国人开发的,他们默认的语言是英语,如果我们中国人使用的话,那就得选择中文去显示,因为,有些人不懂英文。那你可能会想,那直接跟随系统就好了。你系统的文字肯定是你认识的文字。其实这样做是为了方便那些知识渊博的人,他们可能知道多种语言。

了解了需求让我们开始来实现吧!

语言国际化的实现

一,我们要创建不同的strings.xml

一开始我说了strings.xml与国际化相关。确实如此哦 首先我们要在res文件夹下,建不同的values文件夹,每个文件夹下建一个strings.xml,如下图

每个strings.xml中写的是同一个文字不同国家的语言。格式一般为:values-语言代号-地区代号。语言代号,和地区代号是啥,我怎么知道某个语言他的这些是什么,其实这些资料,百度,Google上有的是。这里我就不复制粘贴了。
我上面的文件夹中少了地区代号,因为我的这四种语言都是不同国家的,如果这里面有两种是同一个国家的,比如一个是中文简体,一个是中国台湾繁体,那就要写具体的地区代号了。基本上产品不会让你把每个国家的语言都写上去,基本上就4种左右,主要是看目标用户的地区。那太费时间和精力了,安装包也会弄得很大。最多8种左右。还得请个翻译去翻译这些语言。
中文 :strings.xml
英文 :strings.xml
印度尼西亚:strings.xml

这里要注意两点: 第一,name属性的ID,在不同的strings.xml文件中要一一对应上。
第二,每个文件中的语言要对应,不能在中文的strings.xml写了印度尼西亚语
当你选择了不同的语言时,首先就会去项目中对应国家的语言的values文件去找,如果选择的语言里没有,那就会应用默认的values文件夹下的strings.xml中的文字.
比如,你工程目录中是没有中国台湾繁体的,但是你系统设置了这个语言,他就会使用默认的values文件夹下的strings.xml中的文字。

二、app内做语言切换的功能

做了第一步,只能实现系统设置做切换,app显示不同语言。我们还需要做app内的语言切换。切换界面UI我就不细说了。最重要的就是切换某种语言时,我们要调用哪些代码去设置语言。请看大屏幕:

/**
     * 设置语言
     * 兼容7.0 和8.0以上版本
     */
    public void setConfiguration(Context context) {
        setApplicationContextConfiguration();
        Resources resources = context.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        Configuration config = resources.getConfiguration();
        Locale locale = getLanguageLocale();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
            config.setLocale(locale);
        }else{
            config.locale = locale;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            context.createConfigurationContext(config);
            resources.updateConfiguration(config, dm);
        } else {
            resources.updateConfiguration(config, dm);
        }
    }

上面这段代码是设置语言的核心。其中Locale和Configuration是相关的两个类。Locale就是语言相关的类,它封装了语言相关的信息。Configuration就是语言的配置相关的类。其实,Configuration不仅仅是配置语言的。这里我就不多说了。由于在Android7.0之后把系统语言加入了列表的功能。所以获取系统语言:

//获取系统当前语言对象
    public Locale getSysLocale() {
        Locale locale;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            locale =  Resources.getSystem().getConfiguration().getLocales().get(0);
//            locale =  LocaleList.getDefault().get(0);
        } else {
            locale = Locale.getDefault();
        }
        return locale;
    }

就变成了这样。

三、需要注意的点

1, 并不是在application 中设置语言就万事大吉了。每个activity都需要单独设置,这是比较鸡肋的地方。没办法了,我们只有在BaseActivity中去设置 2,注意在横竖屏切换的时候要重新设置语言 3,不管是系统设置中去切换语言,还是app中切换,都是会充走activity生命周期。要想不重走生命周期,就必须在AndroidManifest.xml对应的activity下添加 configs属性:

<activity android:name=".MainActivity"
            android:label="@string/app_name"
            android:configChanges="locale|layoutDirection">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        

这样就会走onConfigurationChanged()方法了。