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.ENGLISH
、Locale.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