1. 程式人生 > >Android app應用多語言切換功能實現

Android app應用多語言切換功能實現

最近在做一個多語言切換的功能,類似於微信的語言切換,搜了下資料基本上都是以下這種:

1. 實現的效果

和微信類似,在設定介面開啟切換語言的介面,選擇語言後重啟 HomeActivity,語言切換完成,下次重新開啟 App ,也是使用者設定的語言。

2. 實現步驟

1. 新增多語言檔案

在不同的 value 資料夾下(例如 value 、value-en、values-zh-rTW 資料夾)新增不同語言的 string.xml 檔案,我們的專案添加了英文、簡體中文、繁體中文三種語言,如下圖所示:

其中英文需要翻譯,繁體如果沒有專門翻譯的話,可以找個簡繁轉換網站,直接將簡體中文轉成繁體中文,我用的這個網站:

線上中文簡體轉繁體

2. 更新 Configuration 中的 locale 屬性

參照 Android 開發者官網 上 的描述,Configuration 包含了裝置的所有的配置資訊,這些配置資訊會影響應用獲取的資源。例如 string 資源,就是根據 Configuration 的 locale 屬性來判斷該取哪種語言的 string 資源,預設是 value 資料夾下的。

主要程式碼如下:

 Resources resources = getContext().getResources();
 DisplayMetrics dm = resources.getDisplayMetrics();
 Configuration config = resources.getConfiguration();
 // 應用使用者選擇語言
 config.locale = Locale.ENGLISH;
 resources.updateConfiguration(config, dm);

我們用了 Locale 中的預設值 Locale.ENGLISHLocale.TRADITIONAL_CHINESE和 Locale.SIMPLIFIED_CHINESE,如果你需要設定的語言沒有預設值,你可以自己新建一個 Locale 物件,具體自行 Google 吧。

注:跟隨系統設定是 Locale.getDefault()

3. 重啟 HomeActivity

我 們的 App 有個啟動頁 WelcomeActivity,類似微信那個小人啟動頁,如果從歡迎頁重啟,並不是一個好的體驗,應該和微信的語言設定一樣,直接回到 HomeActivity ,而不是從 WelcomeActivity 重新開啟。實現其實也很簡單,程式碼如下:

 Intent intent = new Intent(this, HomeActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 getActivity().startActivity(intent);

正常來說這段程式碼應該是沒問題的,但是假如你的 App 存在某個 activity 和當前設定頁 activity 不在一個 task 棧內的話(比如你從某個通知頁用 FLAG_ACTIVITY_NEW_TASK 啟動的一個 activity),就不會應用語言設定。因此可以直接殺掉當前 App 的程序,保證是“整個”重啟了:

 Intent intent = new Intent(this, HomeActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(intent);
 // 殺掉程序
 android.os.Process.killProcess(android.os.Process.myPid());
 System.exit(0);

按道理殺掉程序的兩行程式碼任意一行即可,但是查閱相關資料,還是兩個都加上吧,如果有詳細瞭解歡迎溝通。此段程式碼其實參考自 CustomActivityOnCrash 開源專案,有興趣的可以研究下這個開源庫捕捉崩潰資訊,重啟應用部分的程式碼。

個人覺得這種重啟HomeActivity的方法太粗暴了而且體驗不好,不過貌似微信也是這麼重啟了HomeActivity。一般語言切換的設定會藏的比較深,比如微信,如果一個使用者對手機操作不熟或者說對這個應用不熟,不小心切換了不知道什麼語言然後給我跳回主頁,再想設回中文就麻煩咯。所以,我認為最好是切完語言立即重新整理然後還是停留當前頁比較好。具體實現如下:

1、還是要新增多語言檔案,跟上面的步驟1一樣;

2、在BaseActivity中實現語言切換程式碼:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    EventBus.getDefault().register(this);
    changeAppLanguage();
}

  public void changeAppLanguage() {
       //這是SharedPreferences工具類,用於儲存設定,程式碼很簡單,自己實現吧
         String sta = Store.getLanuageIsChinese() ? "zh" : "en";
         // 本地語言設定
         Locale myLocale = new Locale(sta);
         Resources res = getResources();
         DisplayMetrics dm = res.getDisplayMetrics();
         Configuration conf = res.getConfiguration();
        conf.locale = myLocale;
         res.updateConfiguration(conf, dm);
   }
 public void onEvent(String str) {
         switch (str) {
            case Constant.EVENT_REFRESH_LANGUAGE:
                 changeAppLanguage();
                 recreate();//重新整理介面
                 break;
         }
     }
 @Override
     protected void onDestroy() {
         super.onDestroy();
         EventBus.getDefault().unregister(this);
     }

3、設定介面中的實現自然就是更新sharedPreferences中的設定,然後傳送EventBus就行啦

       if () {//中文
             Store.setLanuageIsChinese(true);
         } else if () {//英文
             Store.setLanuageIsChinese(false);
         }
         EventBus.getDefault().post(Constant.EVENT_REFRESH_LANGUAGE);

基本思路就是這樣,如果還有什麼更好的方法,敬請給俺留言,讓我膜拜一下。

附:一鍵國際化(機翻)

常見的有:

zh_cn: 簡體中文

zh_hk: 繁體中文(中國香港)  

zh_tw: 繁體中文(中國臺灣地區)

en-hk: 英語(香港)

en_us: 英語(美國)

en_gb: 英語(英國)

en_ww: 英語(全球)

ja_jp: 日語(日本)

ko_kr: 韓文(韓國)

      把UI中的字串儲存在外部檔案,通過程式碼提取,這是一種很好的做法。Android可以通過工程中的資源目錄輕鬆實現這一功能。

      你一建立工程,則在工程的根目錄會建立一個res/的目錄,目錄中包含所有資源型別的子目錄。其中包含工程的預設檔案比如res/values/strings.xml,用於儲存字串值。

建立區域設定目錄及字串檔案

          為支援多國語言,在res/中建立一個額外的values目錄以連字元和ISO國家程式碼結尾命名,比如values-es/是為語言程式碼為"es"的區域設定的簡單的資原始檔的目錄。Android會在執行時根據裝置的區域設定,載入相應的資源。

若決定支援某種語言,則需要建立資源子目錄和字串資原始檔,例如:

YouProject/
res/
values/
strings.xml
        values-es/
strings.xml
        values-fr/
strings.xml

新增不同區域語言的字串值到相應的檔案。

Android系統執行時會根據使用者裝置當前的區域設定,使用相應的字串資源。

例如,下面列舉了幾個不同語言對應不同的字串資原始檔。

英語(預設區域語言),/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
法語,/values-fr/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">Mon Application</string>
<string name="hello_world">Bonjour le monde !</string>
</resources>

使用字元資源

我們可以在原始碼和其他XML檔案中通過<string>元素的name屬性來引用自己的字串資源。

<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"android:text="@string/title"
android:textSize="16sp"/>

在原始碼中可以通過R.string.<string_name>語法來引用一個字串資源,很多方法都可以通過這種方式來接受字串。

例:
// 從資原始檔通過id獲取你要的string資源
String tv_title= getResources().getString(R.string.title);TextView textView = new TextView(this);
textView.setText(tv_title);

然而這是我們傳統的處理方法,現在我們有了一個AndroidStudio的新外掛,讓我們一鍵生成索要使用的資原始檔和目錄,並且裡面的語言也是相對應的國際化語言,是不是方便很多,我們就不再需要自己去生成目錄和檔案,並且拿詞典去翻譯某一段文字(有時翻譯的還不對)。

         聽起來是不是很爽的感覺,當然一般的app是不要實現語言國際化的,但是要實現也是個很大的工程,所以我們通過一鍵實現語言國際化是不是很給力。

一鍵實現語言國際化

  我們要裝的外掛是AndroidLocalizationer從github上down後,整合到studio裡面就好了,看圖:

把下好的zip包解壓,裡面有個同名的壓縮包就是我們的外掛包。 這樣我們就把外掛整合好了。然後找到string.xml--->右鍵————》
這時我們就可以勾選自己要實現的國家的語言了。
這幾十種語言應該涵蓋了所有的吧,猜的

然後我們就來看下成果》》》》》

看見這幾面旗子是不是感覺很開心啊,然後我們來看下strings.xml的內容,果然不負我望:

strings.xml

<resources>
    <string name="app_name">MyZhihuapp</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="file_path">multidownload</string>
    <string name="image_data">imageData</string>
</resources>
再看下values-ja (小日本鬼子的) strings.xml
<resources>   <string name="app_name">MyZhihuapp</string>
   <string name="hello_world">ハローワールド!</string>
   <string name="action_settings">設定</string>
   <string name="file_path">multidownload</string>
   <string name="image_data">imagedata を扱う</string></resources>
接下來看下values-ko(韓國棒子的)strings.xml
<string name="app_name">MyZhihuapp</string>
<string name="hello_world">전 세계 여러분 안녕하세요!</string>
<string name="action_settings">설정</string>
<string name="file_path">multidownload</string>
<string name="image_data">imageData</string>
哈哈,說多了也沒有意思,就是一個studio的外掛,然後主要也是給大家看看效果,感覺還是為開發帶來了很多的便利。個人感覺唯一不足的就是:我們改了values/string.xml裡面的內容其他語言國際化語言不會自動重新編譯(或clean重新編譯),要是這樣都實現了就更完美了偷笑。。。

 轉載自:https://www.cnblogs.com/popqq520/p/5498990.html

http://blog.csdn.net/u013278099/article/details/49865177