1. 程式人生 > >android國際化程式碼動態更改語言環境

android國際化程式碼動態更改語言環境

1.場景

我們都知道,在安卓做國際化的過程中,建立不同的value資料夾,引用不同value資料夾下的string就可以實現國際化,系統會根據手機的語言環境自動匹配語言環境,但有時候我們的應用動態設定語言的功能,這時,我們就要來動態更新我們應用的語言.

語言設定

2.應用

一般像系統設定的一些配置資訊,我們都可以使用Configuration來實現,此時我們會想到我們常用的onConfigurationChanged,我們常用的螢幕橫豎屏切換系統會回撥這個方法,此時需要在清單檔案配置許可權

<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
></uses-permission>

還必須在清單檔案中為Activity配置configChanges資訊,否則系統不會回撥onConfigurationChanged方法,而是重新走生命週期

<activity
      android:name="module.MyActivity"
      android:configChanges="orientation"
      android:screenOrientation="portrait" />

這時我們會發現,我們經常配置configChanges的不僅僅只有orientation啊 還有像keyboardHidden等等,確實是這樣的,其實不僅僅橫豎屏切換時系統會回撥
onConfigurationChanged

,還有像一些軟鍵盤的隱藏和顯示,系統語言環境的改變,系統字型大小的改變都會回撥這個方法,接下來我們來看看configChanges的一些具體的屬性.

3.configChanges的屬性

Value Description
mcc 移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機使用者所屬國家。
mnc 移動網號,在一個國家或者地區中,用於區分手機使用者的服務商。
locale 使用者所在地區發生變化。
touchscreen 螢幕發生變化,正常情況下一般不會發生
keyboard 鍵盤模式發生變化,例如:使用者接入外部鍵盤輸入。
keyboardHidden 系統鍵盤的顯示和隱藏
navigation 導航欄型別發生改變,正常情況下一般不會發生
orientation 裝置旋轉,橫向顯示和豎向顯示模式切換。
fontScale 系統字型縮放發生改變

這裡我們可以看到locale是表示地區發生改變的 ,其實這些屬性都封裝在Configuration裡面 ,下面我們看一下怎麼動態改變語言環境

4.動態更改語言環境

1.首先在我們選擇語言的地方,本地儲存設定的語言資訊,並動態設定語言環境

private void ChooseLan() {

        AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("請選擇語言")
                .setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[]{"中文,English"}), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //獲取系統配置的Locale資訊
                        Locale locale = getResources().getConfiguration().locale;
                        switch (which) {

                            case 0:
                                //在設定語言介面儲存設定的語言環境,在使用者重新進入應用時使應用處於設定後的
                                SpUtils.putParam(MyActivity.this, "language", "chinese");
                                //Locale賦值為當前設定的語言環境
                                locale = Locale.SIMPLIFIED_CHINESE;
                                break;
                            case 1:
                                SpUtils.putParam(MyActivity.this, "language", "english");
                                locale = Locale.ENGLISH;
                                break;

                        }
                        //設定語言環境
                        setLan(locale);
                        dialog.dismiss();
                    }
                }).show();
    }

    private void setLan(Locale locale) {

        // 獲得res資源物件
        Resources resources = getResources();
        // 獲得配置資訊物件
        Configuration config = resources.getConfiguration();
        // 獲得螢幕引數:主要是解析度,畫素等。
        DisplayMetrics dm = resources.getDisplayMetrics();
        // 語言
        config.locale = locale;
        resources.updateConfiguration(config, dm);

        // 重新整理activity才能馬上奏效
        startActivity(new Intent().setClass(this,
                MyActivity.class));
        finish();
    }

2.在進入時,在我們的Application中首先判斷使用者有沒有設定過語言環境,如果設定過就動態設定

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        setLan();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setLan();
    }

    /**設定語言資訊*/
    private void setLan() {

        Locale locale ;
        String language = SpUtils.getStringParam(this, "language", "");
        if (TextUtils.isEmpty(language)){
            //使用者沒有設定,賦值為系統語言環境
            locale=getResources().getConfiguration().locale;
        }else {
            //使用者設定過
            switch (language){
                case "chinese":
                    locale=Locale.SIMPLIFIED_CHINESE;
                    break;
                case "english":
                    locale=Locale.ENGLISH;
                    break;
                default:
                    locale=getResources().getConfiguration().locale;
                    break;
            }
        }

        // 獲得res資源物件
        Resources resources = getResources();
        // 獲得配置資訊物件
        Configuration config = resources.getConfiguration();
        // 獲得螢幕引數:主要是解析度,畫素等。
        DisplayMetrics dm = resources.getDisplayMetrics();
        // 語言
        config.locale = locale;
        //更新配置資訊
        resources.updateConfiguration(config, dm);
    }

}

Note:以上只演示了中英文的切換,支援安卓相容的所有語言的切換,同時在value中有多語言的string資源才能生效.

5.擴充套件

由以上我們可以想到,其實Configuration 所有屬性都可以這樣動態設定,下面我們來試一下動態改變螢幕的橫豎屏切換,不多說了,和設定語言是一樣的,直接上程式碼

   //橫豎屏切換
    int orientation;
    private void setOrientation() {

       orientation = getResources().getConfiguration().orientation;
        button.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               switch (orientation){
                   case Configuration.ORIENTATION_LANDSCAPE://橫屏
                       orientation = Configuration.ORIENTATION_PORTRAIT;
                       break;
                   case Configuration.ORIENTATION_PORTRAIT:
                       orientation=Configuration.ORIENTATION_LANDSCAPE;
                       break;
               }

               Resources resources = getResources();
               Configuration config = getResources().getConfiguration();
               config.orientation=orientation;
               DisplayMetrics displayMetrics = resources.getDisplayMetrics();
               resources.updateConfiguration(config,displayMetrics);

           }
       });
    }