Android应用内设置多语言

Posted 亮亮在江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android应用内设置多语言相关的知识,希望对你有一定的参考价值。

1、项目简介

最近项目中要加入多语言需求,涉及到的有中文简体,中文繁体,英语,西班牙语,泰语,印尼语,葡萄牙语。参考了Android应用内设置多语言,可随系统语言改变而改变,在此基础上做了修改,选择为跟随系统时不再粗暴调用 此方法。android.os.Process.killProcess(android.os.Process.myPid());
直接杀死会有一个类似于崩溃的效果,产品上难以接受。所以跟随系统时查看系统语言单独调用,如果本地string中不存在系统语言对应的语言,那么默认为英语。下面看一下效果图:
因为目前只有一个MainActivity页面,选择语言后切换跳转有闪动,大家可以切换语言后回到首页,就像微信切换语言一样。


 

 2、实现原理

首先在res下创建对应的string对应语言文件

在Application中调用attachBaseContext方法中的初始化,如果本地有sp保存的语言,显示此语言,如果没有就显示系统语言。

protected void attachBaseContext(Context base) 
        //系统语言等设置发生改变时会调用此方法,需要要重置app语言
        super.attachBaseContext(MultiLanguageUtil.attachBaseContext(base));
    
@TargetApi(Build.VERSION_CODES.N)
    private static Context createConfigurationResources(Context context) 
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        Locale appLocale = getAppLocale(context);

        Log.i("language0", appLocale.getLanguage() + "--------" + appLocale.getCountry() + "--------" + appLocale.toLanguageTag());
        Constants.SYSTEM_LANGUAGE = appLocale.getLanguage();
        Constants.SYSTEM_COUNTRY = appLocale.getCountry();
        Constants.SYSTEM_TOLANGUAGETAG = appLocale.toLanguageTag();

        //如果本地有语言信息,以本地为主,如果本地没有使用默认Locale
        Locale locale = null;
        String spLanguage = SPUtils.getLanguageString(context, Constants.LOCALE_LANGUAGE);
        String spCountry = SPUtils.getLanguageString(context, Constants.LOCALE_COUNTRY);
        if (!TextUtils.isEmpty(spLanguage) && !TextUtils.isEmpty(spCountry)) 
            if (isSameLocal(appLocale, spLanguage, spCountry)) 
                locale = appLocale;
             else 
                locale = new Locale(spLanguage, spCountry);
            
         else 
            if (Constants.SYSTEM_TOLANGUAGETAG.contains("zh-Hant")) 
                locale = new Locale(Constants.SYSTEM_LANGUAGE, "TW");
             else if (Constants.SYSTEM_TOLANGUAGETAG.contains("zh-Hans") || Constants.SYSTEM_TOLANGUAGETAG.equals("zh-CN")) 
                locale = new Locale(Constants.SYSTEM_LANGUAGE, "CN");
             else 
                locale = appLocale;
            
        

        configuration.setLocale(locale);
        configuration.setLocales(new LocaleList(locale));
        return context.createConfigurationContext(configuration);
    

在MainActivity主页面initData()方法中显示sp存储过对应的语言,如果为空,那么就选中系统语言

if (!TextUtils.isEmpty(spLanguage) && !TextUtils.isEmpty(spCountry)) 
            if(spLanguage.equals("zh") && spCountry.equals("CN"))
                rbgroup.check(rb1.getId());
             else if(spLanguage.equals("zh") && spCountry.equals("TW"))
                rbgroup.check(rb2.getId());
            else if(spLanguage.equals("en") && spCountry.equals("US"))
                rbgroup.check(rb3.getId());
            else if(spLanguage.equals("es") && spCountry.equals("ES"))
                rbgroup.check(rb4.getId());
            else if(spLanguage.equals("th") && spCountry.equals("TH"))
                rbgroup.check(rb5.getId());
            else if(spLanguage.equals("in") && spCountry.equals("ID"))
                rbgroup.check(rb6.getId());
            else if(spLanguage.equals("pt") && spCountry.equals("PT"))
                rbgroup.check(rb7.getId());
            
         else 
            rbgroup.check(rb0.getId());
        

然后选中语言和取消选中采用的是RadioGroup和RadioButton,选中一种语言设置与之对应的语言和地区

rbgroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() 
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkId) 
                if (checkId == rb0.getId()) 
                    String language = Constants.SYSTEM_LANGUAGE;

                    if (language.equals("zh") && (Constants.SYSTEM_TOLANGUAGETAG.contains("zh-Hans") || Constants.SYSTEM_TOLANGUAGETAG.equals("zh-CN"))) 
                        changeLanguage("zh", "CN",false); //中文简体
                     else if (language.equals("zh") && Constants.SYSTEM_TOLANGUAGETAG.contains("zh-Hant")) 
                        changeLanguage("zh", "TW",false);//中文繁体
                     else if (language.equals("en")) 
                        changeLanguage("en", "US",false);  //英语---默认系统语言
                     else if (language.equals("es")) 
                        changeLanguage("es", "ES",false); //西班牙
                     else if (language.equals("th")) 
                        changeLanguage("th", "TH",false);// 泰语
                     else if (language.equals("in")) 
                        changeLanguage("in", "ID",false);// 印度尼西亚语
                     else if (language.equals("pt")) 
                        changeLanguage("pt", "PT",false);// 葡萄牙
                     else 
                        changeLanguage("en", "US",false);  //英语---默认系统语言
                    

                 else if (checkId == rb1.getId()) 
                    changeLanguage("zh", "CN",true); //中文简体
                 else if (checkId == rb2.getId()) 
                    changeLanguage("zh", "TW",true);//中文繁体
                 else if (checkId == rb3.getId()) 
                    changeLanguage("en", "US",true);  //英语---默认系统语言
                 else if (checkId == rb4.getId()) 
                    changeLanguage("es", "ES",true); //西班牙
                 else if (checkId == rb5.getId()) 
                    changeLanguage("th", "TH",true);// 泰语
                 else if (checkId == rb6.getId()) 
                    changeLanguage("in", "ID",true);// 印度尼西亚语
                 else if (checkId == rb7.getId()) 
                    changeLanguage("pt", "PT",true);// 葡萄牙
                
            
        );

在此处我做的改进是当选中的是系统语言时,判断此时的系统语言是哪种,然后设置与之对应的方法,英语为默认语言。

//修改应用内语言设置
    private void changeLanguage(String language, String area,boolean noSystemLanguage) 
        if(!noSystemLanguage)
            SPUtils.saveLanguageString(MainActivity.this,Constants.LOCALE_LANGUAGE, "");
            SPUtils.saveLanguageString(MainActivity.this,Constants.LOCALE_COUNTRY, "");
        
        //不为空,那么修改app语言,并true是把语言信息保存到sp中,false是不保存到sp中
        Locale newLocale = new Locale(language, area);
        MultiLanguageUtil.changeAppLanguage(MainActivity.this, newLocale, noSystemLanguage);

        //重启app,这一步一定要加上,如果不重启app,可能打开新的页面显示的语言会不正确
        Intent intent = new Intent(MainActivity.this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    

如果为系统语言,sp不再存储数据,反之存储对应的语言数据,如果选择为英语,默认设置为Locale.ENGLISH

public static void changeAppLanguage(Context context, Locale locale, boolean persistence) 
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        Configuration configuration = resources.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
            if (locale.getLanguage().equals("en")) 
                configuration.setLocale(Locale.getDefault());
                configuration.setLocale(Locale.ENGLISH);
             else 
                configuration.setLocale(locale);
                configuration.setLocales(new LocaleList(locale));
            
            context.createConfigurationContext(configuration);
         else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) 
            configuration.setLocale(locale);
         else 
            configuration.locale = locale;
        
        resources.updateConfiguration(configuration, metrics);

        if (persistence) 
            SPUtils.saveLanguageString(context, Constants.LOCALE_LANGUAGE, locale.getLanguage());
            SPUtils.saveLanguageString(context, Constants.LOCALE_COUNTRY, locale.getCountry());
        
    

到此处多语言中主要方法已经介绍完了,希望给予有需要的同学一些帮助,如果有什么疑问欢迎评论留言。最后附上多语言demo  点击下载

最全的android各国语言对照表
在线翻译--多语言

以上是关于Android应用内设置多语言的主要内容,如果未能解决你的问题,请参考以下文章

Android应用内设置多语言

Android应用内切换语言

多语言 ElasticSearch 支持

Android国际化之多语言(配置及应用内设置)✈️

Android 内多语言切换实现

Android 应用内多语言切换