1. 程式人生 > >Android應用程式內部切換語言及自定義語言

Android應用程式內部切換語言及自定義語言

前言:這是小弟的第一篇部落格,琢磨了半天也不知道這玩意怎麼使,因此必然會有很多不足的地方,希望大家多多指點,謝謝!

國際化一直以來也是Android專案中需要考慮到的一個問題,以往我們所接觸到的國際化無非就是在res目錄下新建幾個values資料夾,裡面存放對應國家的資原始檔,當我們更改手機系統語言後,APP的語言也會跟著變化。而我今天要說的是在應用程式內部進行語言切換,沒錯,就是跟我們常用的微信一樣,改變的只是當前APP的語言。一開始,我覺得這麼做似乎並沒有什麼意義,使用者想要切換手機語言,直接改變系統語言不就行了嗎?直到我拿著我的HTC進行語言切換時才發現,只有English、簡體中文和繁體中文供我切換,那我相信應該不止HTC手機會這樣吧,這樣看來,專案內部切換語言還是有其存在的必要性的。
初次遇到這樣的需求,我能想的就是求助於廣大的網友,上網搜了下解決辦法,辦法確實有不少,但恕我愚昧,能看懂的就這一種,而且也是經過了好幾篇文章的指點才東拼西湊的湊齊了,好了,廢話不多說,來看看是如何實現的吧。。。

首先,同樣的需要在res目錄下準備多套語言values檔案,這裡就不多說了。。。
這裡寫圖片描述
然後,在專案的父層類,也就是基類(一般是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);
    }
}

至此,小弟的第一篇部落格就完了,歡迎大家多提意見和建議,謝謝!