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);
}
}
至此,小弟的第一篇部落格就完了,歡迎大家多提意見和建議,謝謝!