添加多国语言文件

下面以添加 西班牙语 为例,首先在 res 右键 “new”,选择 “Values resource file”。

左侧选中 “Locale”,点击 “ >> ”,然后 “Chosen qualifiers” 面板中就会出现 “Locale” 这栏

西班牙语是 “es”,在 “Language” 面板中最开始是没有搜索框的,直接聚焦后输入,搜索框就会自动出现了。然后在右边的 “Specific Region Only” 面版中 选择 “Any Region”。

多语言表(转自 https://blog.csdn.net/u010586698/article/details/56673379)

语言 英语名称 中文名称 国家码 国标
Language English Name Chinese Name Code GB ICS JB KK L
العربية Arabic(Israel) 阿拉伯语(以色列) ar_IL Y Y Y Y Y
Arabic(Egypt) 阿拉伯语(埃及) ar_EG GD_MN GD_MN GD_MN GD_MN GD_MN
中文 Chinese Simplified 中文简体 zh_CN Y Y Y Y Y
中文 Chinese Tradition 中文繁体 zh_TW Y Y Y Y Y
中文 Chinese 中文(香港) zh_HK N N P P Y
Nederlands Dutch (Netherlands) 荷兰语 nl_NL Y Y Y Y Y
Nederlands Dutch (Netherlands) 荷兰语(比利时) nl_BE GD_MN GD_MN GD_MN GD_MN GD_MN
English English English(United States) 英语(美国) en_US Y Y Y Y
English English(Australia) 英语(澳大利亚) en_AU GD_MN GD_MN GD_MN GD_MN GD_MN
English English(Canada) 英语(加拿大) en_CA GD_MN GD_MN GD_MN GD_MN GD_MN
English English(India) 英语(印度) en_IN GD_MN GD_MN GD_MN GD_MN GD_MN
English English(Ireland) 英语(爱尔兰) en_IE GD_MN GD_MN GD_MN GD_MN GD_MN
English English(New Zealand) 英语(新西兰) en_NZ GD_MN GD_MN GD_MN GD_MN GD_MN
English English(Singapore) 英语(新加波) en_SG GD_MN GD_MN GD_MN GD_MN GD_MN
English English(South Africa) 英语(南非) en_ZA GD_MN GD_MN GD_MN GD_MN GD_MN
English English(United Kingdom) 英语(英国) en_GB GD_MN GD_MN GD_MN Y Y
Français French 法语 fr_FR Y Y Y Y Y
Français French 法语(比利时) fr_BE GD_MN GD_MN GD_MN GD_MN GD_MN
Français French 法语(加拿大) fr_CA GD_MN GD_MN GD_MN GD_MN GD_MN
Français French 法语(瑞士) fr_CH GD_MN GD_MN GD_MN GD_MN GD_MN
Deutsch German 德语 de_DE Y Y Y Y Y
Deutsch German 德语(列支敦斯登) de_LI GD_MN GD_MN GD_MN GD_MN GD_MN
Deutsch German 德语(奥地利) de_AT GD_MN GD_MN GD_MN Y Y
Deutsch German 德语(瑞士) de_CH GD_MN GD_MN GD_MN GD_MN GD_MN
Italiano Italian 意大利语 it_IT Y Y Y Y Y
Italiano Italian 意大利语(瑞士) it_CH GD_MN GD_MN GD_MN GD_MN GD_MN
Protuguês Portuguese 葡萄牙语(巴西) Pt_BR Y Y Y Y Y
Protuguês Portuguese 葡萄牙语 Pt_PT Y Y Y Y Y
Español Spanish 西班牙语 es_ES Y Y Y Y Y
Español Spanish 西班牙语(美国) es_US GD_MN GD_MN P Y Y
বাংলা Bengali 孟加拉语 bn_BD Y N N N Y
বাংলা Bengali 孟加拉语(印度) bn_IN Y Y Y Y Y
hrvatski Croatian 克罗地亚语 hr_HR GD_MN GD_MN P Y Y
čeština Czech 捷克语 cs_CZ Y Y Y Y Y
Dansk Danish 丹麦语 da_DK GD_MN GD_MN P Y Y
ελληνικά Greek 希腊语 el_GR GD_MN Y Y Y Y
עברית Hebrew 希伯来语(以色列) he_IL GD_MN GD_MN GD_MN GD_MN GD_MN
עברית Hebrew 希伯来语(以色列) iw_IL GD_MN GD_MN Y Y Y
हिंदी Hindi 印度语 hi_IN Y Y Y Y Y
Magyar Hungarian 匈牙利语 hu_HU GD_MN Y Y Y Y
Indonesian 印度尼西亚语 in_ID Y Y Y Y Y
日本語の言語 Japanese 日语 ja_JP GD_MN GD_MN P P Y
한국의 Korean 韩语(朝鲜语) ko_KR GD_MN GD_MN Y Y Y
Bahasa Melayu Malay 马来语 ms_MY Y Y Y Y Y
فارسی Perisan 波斯语 fa_IR Y Y Y Y Y
Polski Polish 波兰语 Pl_PL GD_MN GD_MN P Y Y
româna Romanian 罗马尼亚语 ro_RO GD_MN Y Y Y Y
Русский Russian 俄罗斯语 ru_RU Y Y Y Y Y
српски Serbian 塞尔维亚语 sr_RS GD_MN GD_MN P P Y
Svenska Swedish 瑞典语 sv_SE GD_MN GD_MN P Y Y
ไทย Thai 泰语 th_TH Y Y Y Y Y
Türkçe Turkey 土耳其语 tr_TR Y Y Y Y Y
اردو Urdu 乌尔都语 ur_PK Y Y Y Y Y
tiếng việt Vietnamese 越南语 vi_VN Y Y Y Y Y
catalá Catalan 加泰隆语(西班牙) ca_ES GD_MN GD_MN P P Y
latviešu Latviesu 拉脱维亚语 lv_LV GD_MN GD_MN P Y Y
Lietuvių Lithuanian 立陶宛语 lt_LT GD_MN GD_MN P Y Y
Norsk bokmal Norwegian 挪威语 Nb_NO GD_MN GD_MN P Y Y
Slovenčina slovencina 斯洛伐克语 sk_SK GD_MN GD_MN P Y Y
Slovenščina Slovenian 斯洛文尼亚语 sl_SI GD_MN GD_MN P P Y
български bulgarian 保加利亚语 bg_BG GD_MN GD_MN P Y Y
українська Ukrainian 乌克兰语 uk_UA GD_MN GD_MN P Y Y
Tagalog Filipino 菲律宾语 tl_PH GD_MN Y Y Y Y
Suomi Finnish 芬兰语 fi_FI GD_MN GD_MN P Y Y
Afrikaans Afrikaans 南非语 af_ZA N GD_MN GD_MN GD_MN GD_MN
Rumantsch Romansh 罗曼什语(瑞士) rm_CH GD_MN GD_MN GD_MN GD_MN GD_MN
ဗမာ Burmese(Zawgyi) 缅甸语(民间) my_ZG N N P P Y
ဗမာ Burmese(Paduak) 缅甸语(官方) my_MM N N Y Y Y
ខ្មែរ Khmer 柬埔寨语 km_KH N N Y Y Y
አማርኛ Amharic 阿姆哈拉语(埃塞俄比亚) am_ET N GD_MN GD_MN GD_MN GD_MN
беларуская Belarusian 白俄罗斯语 be_BY N GD_MN GD_MN GD_MN GD_MN
eesti Estonian 爱沙尼亚语 et_EE N GD_MN P P Y
Kiswahili Swahili 斯瓦希里语(坦桑尼亚) sw_TZ N GD_MN GD_MN GD_MN GD_MN
isiZulu Zulu 祖鲁语(南非) zu_ZA N GD_MN GD_MN GD_MN GD_MN
azərbaycanca Azerbaijani 阿塞拜疆语 az_AZ N N N GD_MN GD_MN
Հայերէն Armenian 亚美尼亚语(亚美尼亚) hy_AM N N P P Y
ქართული Georgian 格鲁吉亚语(格鲁吉亚) ka_GE N N N GD_MN GD_MN
ລາວ Laotian 老挝语(老挝) lo_LA N N N GD_MN GD_MN
Монгол Mongolian 蒙古语 mn_MN N N N GD_MN GD_MN
नेपाली Nepali 尼泊尔语 ne_NP N N N GD_MN GD_MN
қазақ тілі Kazakh 哈萨克语 kk_KZ N N P P Y
Galego Galician 加利西亚语 gl-rES N N N N GD_MN
íslenska Icelandic 冰岛语 is-rIS N N N N GD_MN
ಕನ್ನಡ Kannada 坎纳达语 kn-rIN N N N N GD_MN
кыргыз тили; قىرعىز تىلى Kyrgyz 吉尔吉斯语 ky-rKG N N N N GD_MN
മലയാളം Malayalam 马拉亚拉姆语 ml-rIN N N N N GD_MN
मराठी Marathi 马拉提语/马拉地语 mr-rIN N N N N GD_MN
தமிழ் Tamil 泰米尔语 ta-rIN N N N N GD_MN
македонски јазик Macedonian 马其顿语 mk-rMK N N N N GD_MN
తెలుగు Telugu 泰卢固语 te-rIN N N N N GD_MN
Ўзбек тили Uzbek 乌兹别克语 uz-rUZ N N N N GD_MN
Euskara Basque 巴斯克语 eu-rES N N N N GD_MN
සිංහල Sinhala 僧加罗语(斯里兰卡) si_LK N N N N N

下面我做一个支持默认、中文、英文、西班牙语的实例

分别创建如下文件

实现方案:

  • 通过数组存储字符串的ID
    arrays.xml
<?xml version="1.0" encoding="utf-8"?>            @string/language_default        @string/language_zh        @string/language_en        @string/language_es    
  • 切换语言的工具类(安卓7为分界,有两种不同的处理方案)
    LanguageUtil.java
public class LanguageUtil {    private static final String SP_NAME = "LanguageSP";    private static final String LANGUAGE_INDEX = "LanguageIndex";    private static LanguageUtil instance;    private Context context;    private int[] languageIds;    public static LanguageUtil getInstance(Context context) {        if (instance == null) {            instance = new LanguageUtil(context);        } else {            instance.context  = context;        }        return instance;    }    private LanguageUtil(Context context) {        this.context = context;        final Resources resources = context.getResources();        TypedArray ta = resources.obtainTypedArray(R.array.language_ids);        languageIds = new int[ta.length()];        for (byte i = 0; i < ta.length(); i++) {            languageIds[i] = ta.getResourceId(i, 0);        }    }    /**     * 获取语言的字符串数组     */    private String[] getLanguages() {        final String[] languages = new String[languageIds.length];        for (byte i = 0; i < languageIds.length; i++) {            languages[i] = context.getString(languageIds[i]);        }        return languages;    }    /**     * 根据索引拿到国际化区域类     */    private Locale getLocale(int index) {        Locale locale;        switch(languageIds[index]) {            case R.string.language_en:                locale = Locale.ENGLISH;                break;            case R.string.language_es:                locale = new Locale("es");                break;            case R.string.language_zh:                locale = Locale.CHINA;                break;            default:                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                    locale = LocaleList.getDefault().get(0);                } else {                    locale = Locale.getDefault();                }                break;        }        return locale;    }    /**     * 在 API 24(Android 7.0)后需要在重启后替换 Context 才能切换语言     * ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象     */    private Context attachBaseContext(int index) {        Resources resources = context.getResources();        Configuration configuration = resources.getConfiguration();        Locale locale = getLocale(index);        configuration.setLocale(locale);        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            configuration.setLocale(locale);            context = context.createConfigurationContext(configuration);        } else {            DisplayMetrics dm = resources.getDisplayMetrics();            resources.updateConfiguration(configuration, dm);        }        return context;    }    /**     * 重启 Activity     */    private void recreate(final Activity activity) {//        activity.runOnUiThread(new Runnable() {//            @Override//            public void run() {//重启 Activity(这个方法一定要在主线程中被调用)//注意:recreate 这个方法有的问题,有时候会闪屏,就是一个界面跳两次出来//recreate之后不能finish,会崩溃//                activity.recreate();//            }//        });        //重启 Activity        Intent intent = new Intent(context, activity.getClass());        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);        activity.startActivity(intent);        activity.finish();    }    private void saveIndexToPreference(int index) {        SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);        SharedPreferences.Editor et = sp.edit();        et.putInt(LANGUAGE_INDEX, index);        et.commit();    }    private int getIndexFromPreference() {        SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);        return sp.getInt(LANGUAGE_INDEX, 0);    }    public void changeLanguage(int index, Activity activity) {        saveIndexToPreference(index);        attachBaseContext(index);        recreate(activity);    }        /**     * 每次Activity启动时都会去寻找默认的语言配置,所以必须在分配Context之前进行预处理,修改成你所需要的配置。     * 这个预处理方法就是 attachBaseContent     */    public Context restoreLanguage() {        int index = getIndexFromPreference();        return attachBaseContext(index);    }}
  • 所有Activity都必须继承一个基类,在基类的 attachBaseContext 方法中切换语言
    BaseInternationalActivity.java
public abstract class BaseInternationalActivity extends AppCompatActivity {    @Override    protected void attachBaseContext(Context newBase) {        newBase= LanguageUtil.getInstance(newBase).restoreLanguage();        super.attachBaseContext(newBase);    }}

注意事项

上面的方法只会更新 activity 的 context,对于 application 和 service 的 context 并不会被改变。
虽然 application 和 service 也有 attachBaseContext,只会在初次打开时被替换。
而且这里只用了 activity.recreate() 影响的只会是当前的 Activity, 其它的 activity 启动的时候还是使用默认的 context。

所以如果要用到 service 里面的 context,我的做法是 比如在 bind 的时候重新设置它的context

attachBaseContext (转自 https://www.jianshu.com/p/94e0f9ab3f1d)


Context类本身是一个纯abstract类,它有两个具体的实现子类:ContextImpl和ContextWrapper。其中ContextWrapper类,如其名所言,这只是一个包装而已,ContextWrapper构造函数中必须包含一个真正的Context引用,同时ContextWrapper中提供了attachBaseContext()用于给ContextWrapper对象中指定真正的Context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。

更多相关文章

  1. Android(安卓)APP 中英文切换
  2. Android遇上Kotlin | Kotlin若只如初见
  3. Android(安卓)客户端与服务端JSP相互传递中文
  4. Android学习笔记之解决下载中中文文件名问题
  5. Android(安卓)socket通信,读去中文汉字乱码问题解决。
  6. Android(安卓)中文 API(123) ―― AbsListView(二)
  7. Android(安卓)SDK 3.0正式放出 —— 我的使用感受(2/23更新)
  8. Android(安卓)Permission 中文说明
  9. TSwitch 中文简繁显示支持(XE6 Android)

随机推荐

  1. 从零搭建 repo 服务器
  2. android 在java代码中动态设置控件的位置
  3. Android系列开发博客资源汇总
  4. android手机开发(一)环境配置
  5. Android界面编程——对话框控件(四)
  6. android SQLite 总结
  7. Ubuntu下使用git和repo下载Android的源代
  8. [RK3399—Android7.1] 去掉设置中的WIFI
  9. Android中Activity和Intent之间的联系
  10. Drawable分类