Android应用程序内部切换语言及自定义语言

前言:这是小弟的第一篇博客,琢磨了半天也不知道这玩意怎么使,因此必然会有很多不足的地方,希望大家多多指点,谢谢!

国际化一直以来也是Android项目中需要考虑到的一个问题,以往我们所接触到的国际化无非就是在res目录下新建几个values文件夹,里面存放对应国家的资源文件,当我们更改手机系统语言后,APP的语言也会跟着变化。而我今天要说的是在应用程序内部进行语言切换,没错,就是跟我们常用的微信一样,改变的只是当前APP的语言。一开始,我觉得这么做似乎并没有什么意义,用户想要切换手机语言,直接改变系统语言不就行了吗?直到我拿着我的HTC进行语言切换时才发现,只有English、简体中文和繁体中文供我切换,那我相信应该不止HTC手机会这样吧,这样看来,项目内部切换语言还是有其存在的必要性的。
初次遇到这样的需求,我能想的就是求助于广大的网友,上网搜了下解决办法,办法确实有不少,但恕我愚昧,能看懂的就这一种,而且也是经过了好几篇文章的指点才东拼西凑的凑齐了,好了,废话不多说,来看看是如何实现的吧。。。

首先,同样的需要在res目录下准备多套语言values文件,这里就不多说了。。。
Android应用程序内部切换语言及自定义语言_第1张图片
然后,在项目的父层类,也就是基类(一般是BaseActivity)中进行语言类型的设置,原则是使用Android开放的API更改Configuration,同时把语言类型保存下来

protected void selectLanguage(String language) {
        //设置语言类型
        Resources resources = getResources();
        Configuration configuration = resources.getConfiguration();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        switch (language) {
            case "en":
                configuration.locale = Locale.ENGLISH;
                break;
            case "ru":
                configuration.locale = Locale_Russia;
                break;
            case "zh":
                configuration.locale = Locale.SIMPLIFIED_CHINESE;
                break;
            default:
                configuration.locale = Locale.getDefault();
                break;
        }
        resources.updateConfiguration(configuration, displayMetrics);

        //保存设置语言的类型
        SharedPreferenceUtils.putString("language", language);
}

紧接着,只要你的应用不彻底从Dalvik或ART中彻底移除,上述操作就可以满足需求了,但是如果重新开机或者强制杀掉应用后,再次启动时需要恢复到以前的语言类型时,我们就需要在onCreate方法中调用方法:

selectLanguage(SharedPreferenceUtils.getString("language", "zh"));

最后,我们需要destory当前页面,重新onCreate才能更改语言类型,正如微信里切换语言后会跳到首页的道理一样:

public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_chinese:
                switchLanguage("zh");
                break;
            case R.id.tv_english:
                switchLanguage("en");
                break;
            case R.id.tv_russian:
                switchLanguage("ru");
                break;
        }

        //更新完语言后需要finish掉当前Activity,然后重新绘制
        finish();
        Intent intent = new Intent(MainActivity.this, MainActivity.class);
        startActivity(intent);
    }

至此,应用内部切换语言的功能就已经可以实现了,不过细心的同学有没有发现我在设置俄语的时候,用到的是Locale_Russia,并非像中文或者英文那样,原因是Locale类中并没有找到俄语,不要问为什么没有,我也想知道原因,而我当时开发的项目中正好又需要俄语,于是就尴尬了,后来也是非常感谢一位网友的热心帮忙才帮我解决了这个问题。其实Locale类中有很多语言是没有的,那如果碰到像我这样需要俄语的该怎么办呢,这就是要说到的第二个问题:如何自定义语言?
其实很简单,就直接上代码了:

public static final Locale Locale_Russia = new Locale("RU","ru","");//自定义俄语

虽说Locale源码中没有俄语,但它却提供了对外新建语言的方法,还有其他源码中没有的语言的新建都可以参照这样进行,但要注意的是new Locale时,后面三个参数的正确填写方式:
参数一:表示language,必须是大写,而且是缩写,缩写的规格还得正确,当初我在自定义俄语的时候写成了RUS,结果愣是没法切换过来,所以如果你觉得自己的代码真的没有任何问题,不妨查看一下格式有没有写错,至于其他语言的格式,大家可以去网上搜搜;
参数二:表示的是country,小写的缩写,缩写规格跟你在建立资源文件是一样的;
参数三:variant,不知道什么鬼,一般就直接写成空双引号就行。
如此一来,应用程序内部切换语言就已经大功告成了,代码其实就那么几行,接下来就把两个主类Activity的源代码贴出来:

public class BaseActivity extends Activity {

    private static final Locale Locale_Russia = new Locale("RU", "ru", "");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedPreferenceUtils.init(this);
        //重启之后恢复到之前的语言
        selectLanguage(SharedPreferenceUtils.getString("language", "zh"));
    }

    protected void selectLanguage(String language) {
        //设置语言类型
        Resources resources = getResources();
        Configuration configuration = resources.getConfiguration();
        DisplayMetrics displayMetrics = resources.getDisplayMetrics();
        switch (language) {
            case "en":
                configuration.locale = Locale.ENGLISH;
                break;
            case "ru":
                configuration.locale = Locale_Russia;
                break;
            case "zh":
                configuration.locale = Locale.SIMPLIFIED_CHINESE;
                break;
            default:
                configuration.locale = Locale.getDefault();
                break;
        }
        resources.updateConfiguration(configuration, displayMetrics);

        //保存设置语言的类型
        SharedPreferenceUtils.putString("language", language);
    }
}
public class MainActivity extends BaseActivity implements View.OnClickListener {

    private Dialog mDialog;
    TextView mTextView, mTextViewCh, mTextViewEn, mTextViewRu;
    Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv_text);
        mButton = (Button) findViewById(R.id.btn_switch_language);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }

    public void showDialog() {
        if (mDialog == null) {
            mDialog = new Dialog(this, R.style.Language_Dialog_Theme);
            LayoutInflater inflater = LayoutInflater.from(this);
            View view = inflater.inflate(R.layout.dialog_language_select, null);
            mDialog.setContentView(view);
            mDialog.setCanceledOnTouchOutside(false);
            mTextViewCh = (TextView) mDialog.findViewById(R.id.tv_chinese);
            mTextViewEn = (TextView) mDialog.findViewById(R.id.tv_english);
            mTextViewRu = (TextView) mDialog.findViewById(R.id.tv_russian);
            mTextViewCh.setOnClickListener(this);
            mTextViewEn.setOnClickListener(this);
            mTextViewRu.setOnClickListener(this);
        }
        mDialog.show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_chinese:
                selectLanguage("zh");
                break;
            case R.id.tv_english:
                selectLanguage("en");
                break;
            case R.id.tv_russian:
                selectLanguage("ru");
                break;
        }

        //更新完语言后需要finish掉当前Activity,然后重新绘制
        finish();
        Intent intent = new Intent(MainActivity.this, MainActivity.class);
        startActivity(intent);
    }
}

至此,小弟的第一篇博客就完了,欢迎大家多提意见和建议,谢谢!

参考:
http://my.oschina.net/jack1900/blog/290694
http://blog.csdn.net/qq_16064871/article/details/50332473

你可能感兴趣的:(Android开发)