微信公衆號:CodingAndroid
CSDN:blog.csdn.net/xinpengfei5…
聲明:本文由CodingAndroid原創,未經受權,不可隨意轉載!css
最近,咱們公司的業務已經拓展到了香港,咱們都知道香港使用的是繁體中文,所以,咱們的APP要能夠設置繁體語言,這不咱們要緊跟國際的步伐,實現多語言,產品定給咱們的需求主要以實現簡體中文、繁體中文、英文三種語言切換便可,具體的業務邏輯是:當用戶第一次進入APP時,App的語言跟隨當前系統語言,當用戶設置了某種語言以後就切換爲用戶設置的語言,無論系統以後設置成哪一種語言,都不會影響用戶設置的語言,若是用戶一直沒有設置語言選項,只要系統語言改變時,APP的語言也要跟隨系統語言設置改變。java
說明:本文以實現簡體中文、繁體中文和英語爲例進行簡要講解。android
咱們能夠預先使用SharedPreference來保存一個語言類型的值,當用戶第一次進入APP時,咱們經過Key取出這個值,第一次確定是取不到的,這時咱們將App的語言設置爲當前系統默認值便可;當用戶通設置多語言時,咱們將這個語言對應的值經過SharedPreference保存到本地便可,而後此時重啓APP,設置爲用戶設置的語言便可,之後每次進入App時只需取出保存用戶設置的語言設置便可,通常設置語言寫在程序的入口 Application 的 onCreate() 方法裏。git
做用:用於保存當前設置語言的類型,此文以SharedPreference保存爲例,固然使用數據庫或者其餘保存方式也是能夠的。github
/**
* Created by xpf on 2017/03/25 :)
* Function: sp存儲的工具類
*/
public class SpUtil {
private static final String APP_SP = "app_sp";
private static final String TAG = SpUtil.class.getSimpleName();
private SpUtil() {
}
private static SpUtil instance = new SpUtil();
private static SharedPreferences mSp = null;
public static SpUtil getInstance() {
if (mSp == null) {
mSp = MyApplication.getContext().getSharedPreferences(APP_SP, Context.MODE_PRIVATE);
}
return instance;
}
/**
* 保存數據
*
* @param key 鍵
* @param value 值
*/
public void save(String key, Object value) {
if (value == null) {
Log.e(TAG, "value==null保存失敗");
return;
}
if (value instanceof String) {
mSp.edit().putString(key, (String) value).commit();
} else if (value instanceof Boolean) {
mSp.edit().putBoolean(key, (Boolean) value).commit();
} else if (value instanceof Integer) {
mSp.edit().putInt(key, (Integer) value).commit();
}
}
/**
* 讀取String類型數據
*
* @param key
* @param defValue
* @return
*/
public String getString(String key, String defValue) {
return mSp.getString(key, defValue);
}
/**
* 讀取boolean類型數據
*
* @param key
* @param defValue
* @return
*/
public boolean getBoolean(String key, boolean defValue) {
return mSp.getBoolean(key, defValue);
}
/**
* 讀取boolean類型數據
*
* @param key
* @param defValue
* @return
*/
public int getInt(String key, int defValue) {
return mSp.getInt(key, defValue);
}
/**
* 清除全部保存的數據(xxx.xml仍然存在,可是內部沒有數據)
*/
public void clearAll() {
mSp.edit().clear().commit();
}
}
複製代碼
做用:用於設置保存語言及獲取當前語言,重啓APP等操做數據庫
public class LocaleUtil {
/**
* 獲取用戶設置的Locale
*
* @return Locale
*/
public static Locale getUserLocale() {
int currentLanguage = SpUtil.getInstance().getInt("currentLanguage", 0);
Locale myLocale = Locale.SIMPLIFIED_CHINESE;
switch (currentLanguage) {
case 0:
myLocale = Locale.SIMPLIFIED_CHINESE;
break;
case 1:
myLocale = Locale.ENGLISH;
break;
case 2:
myLocale = Locale.TRADITIONAL_CHINESE;
break;
}
return myLocale;
}
/**
* 設置語言:若是以前有設置就遵循設置若是沒設置過就跟隨系統語言
*/
public static void changeAppLanguage(Context context) {
if (context == null) return;
Context appContext = context.getApplicationContext();
int currentLanguage = SpUtil.getInstance().getInt("currentLanguage", -1);
Locale myLocale;
// 0 簡體中文 1 繁體中文 2 English
switch (currentLanguage) {
case 0:
myLocale = Locale.SIMPLIFIED_CHINESE;
break;
case 1:
myLocale = Locale.TRADITIONAL_CHINESE;
break;
case 2:
myLocale = Locale.ENGLISH;
break;
default:
myLocale = appContext.getResources().getConfiguration().locale;
}
// 本地語言設置
if (needUpdateLocale(appContext, myLocale)) {
updateLocale(appContext, myLocale);
}
}
/**
* 保存設置的語言
*
* @param currentLanguage index
*/
public static void changeAppLanguage(Context context, int currentLanguage) {
if (context == null) return;
Context appContext = context.getApplicationContext();
SpUtil.getInstance().save("currentLanguage", currentLanguage);
Locale myLocale = Locale.SIMPLIFIED_CHINESE;
// 0 簡體中文 1 繁體中文 2 English
switch (currentLanguage) {
case 0:
myLocale = Locale.SIMPLIFIED_CHINESE;
break;
case 1:
myLocale = Locale.TRADITIONAL_CHINESE;
break;
case 2:
myLocale = Locale.ENGLISH;
break;
}
// 本地語言設置
if (LocaleUtil.needUpdateLocale(appContext, myLocale)) {
LocaleUtil.updateLocale(appContext, myLocale);
}
Toast.makeText(appContext, appContext.getString(R.string.set_success), Toast.LENGTH_SHORT).show();
restartApp(appContext);
}
/**
* 重啓app生效
*
* @param context
*/
public static void restartApp(Context context) {
Intent intent = new Intent(context, MainActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
/**
* 獲取當前的Locale
*
* @param context Context
* @return Locale
*/
public static Locale getCurrentLocale(Context context) {
Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多語言設置獲取頂部的語言
locale = context.getResources().getConfiguration().getLocales().get(0);
} else {
locale = context.getResources().getConfiguration().locale;
}
return locale;
}
/**
* 更新Locale
*
* @param context Context
* @param locale New User Locale
*/
public static void updateLocale(Context context, Locale locale) {
if (needUpdateLocale(context, locale)) {
Configuration configuration = context.getResources().getConfiguration();
if (Build.VERSION.SDK_INT >= 19) {
configuration.setLocale(locale);
} else {
configuration.locale = locale;
}
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
context.getResources().updateConfiguration(configuration, displayMetrics);
}
}
/**
* 判斷需不須要更新
*
* @param context Context
* @param locale New User Locale
* @return true / false
*/
public static boolean needUpdateLocale(Context context, Locale locale) {
return locale != null && !getCurrentLocale(context).equals(locale);
}
/**
* 當系統語言發生改變的時候仍是繼續遵循用戶設置的語言
*
* @param context
* @param newConfig
*/
public static void setLanguage(Context context, Configuration newConfig) {
if (context == null) return;
Context appContext = context.getApplicationContext();
int currentLanguage = SpUtil.getInstance().getInt("currentLanguage", -1);
Locale locale;
// 0 簡體中文 1 繁體中文 2 English
switch (currentLanguage) {
case 0:
locale = Locale.SIMPLIFIED_CHINESE;
break;
case 1:
locale = Locale.TRADITIONAL_CHINESE;
break;
case 2:
locale = Locale.ENGLISH;
break;
default:
locale = appContext.getResources().getConfiguration().locale;
}
// 系統語言改變了應用保持以前設置的語言
if (locale != null) {
Locale.setDefault(locale);
Configuration configuration = new Configuration(newConfig);
if (Build.VERSION.SDK_INT >= 19) {
configuration.setLocale(locale);
} else {
configuration.locale = locale;
}
appContext.getResources().updateConfiguration(configuration, appContext.getResources().getDisplayMetrics());
}
}
}
複製代碼
@Override
public void onCreate() {
super.onCreate();
LocaleUtil.changeAppLanguage(this);
}
複製代碼
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.e("TAG", "onConfigurationChanged");
LocaleUtil.setLanguage(mContext, newConfig);
}
複製代碼
當用戶點擊保存時傳入當前語言對應的Index值便可,我這裏使用的是保存一個Int類型的值,每個Int類型的值對應一種語言的類型,固然你能夠根據本身的實現保存爲String類型也是能夠的。微信
LocaleUtil.changeAppLanguage(mContext, currentLanguage);
複製代碼
本文只以簡體中文、繁體中文和英語爲例,要想實現更多語言設置,請參考下表:app
國家 | Folder Name |
---|---|
中文(中國) | values-zh-rCN |
中文(臺灣) | values-zh-rTW |
中文(香港) | values-zh-rHK |
英語(美國) | values-en-rUS |
英語(英國) | values-en-rGB |
英文(澳大利亞) | values-en-rAU |
英文(加拿大) | values-en-rCA |
英文(愛爾蘭) | values-en-rIE |
英文(印度) | values-en-rIN |
英文(新西蘭) | values-en-rNZ |
英文(新加坡) | values-en-rSG |
英文(南非) | values-en-rZA |
阿拉伯文(埃及) | values-ar-rEG |
阿拉伯文(以色列) | values-ar-rIL |
保加利亞文 | values-bg-rBG |
加泰羅尼亞文 | values-ca-rES |
捷克文 | values-cs-rCZ |
丹麥文 | values-da-rDK |
德文(奧地利) | values-de-rAT |
德文(瑞士) | values-de-rCH |
德文(德國) | values-de-rDE |
德文(列支敦士登) | values-de-rLI |
希臘文 | values-el-rGR |
西班牙文(西班牙) | values-es-rES |
西班牙文(美國) | values-es-rUS |
芬蘭文(芬蘭) | values-fi-rFI |
法文(比利時) | values-fr-rBE |
法文(加拿大) | values-fr-rCA |
法文(瑞士) | values-fr-rCH |
法文(法國) | values-fr-rFR |
希伯來文 | values-iw-rIL |
印地文 | values-hi-rIN |
克羅里亞文 | values-hr-rHR |
匈牙利文 | values-hu-rHU |
印度尼西亞文 | values-in-rID |
意大利文(瑞士) | values-it-rCH |
意大利文(意大利) | values-it-rIT |
日文 | values-ja-rJP |
韓文 | values-ko-rKR |
立陶宛文 | valueslt-rLT |
拉脫維亞文 | values-lv-rLV |
挪威博克馬爾文 | values-nb-rNO |
荷蘭文(比利時) | values-nl-BE |
荷蘭文(荷蘭) | values-nl-rNL |
波蘭文 | values-pl-rPL |
葡萄牙文(巴西) | values-pt-rBR |
葡萄牙文(葡萄牙) | values-pt-rPT |
羅馬尼亞文 | values-ro-rRO |
俄文 | values-ru-rRU |
斯洛伐克文 | values-sk-rSK |
斯洛文尼亞文 | values-sl-rSI |
塞爾維亞文 | values-sr-rRS |
瑞典文 | values-sv-rSE |
泰文 | values-th-rTH |
塔加洛語 | values-tl-rPH |
土耳其文 | values--r-rTR |
烏克蘭文 | values-uk-rUA |
越南文 | values-vi-rVN |
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
複製代碼
在實現APP種切換語言時,試了試微信的多語言設置頁面是在4級頁面,當它設置完語言以後先是跳轉到我 界面(一級頁面),而後緊接着跳到設置界面(二級頁面),貌似微信沒有重啓App,它只是管理保存了Activity任務棧,最後跳轉到設置界面,而個人例子只是重啓了App沒有跳轉回到設置界面,固然這要看具體的需求了,我我的感受,設置完就沒有必要再跳轉回去了。ide
最後附上Demo:
github.com/xinpengfei5…工具
若是你以爲不錯能夠幫我點個star,3Q~
若在使用過程當中遇到什麼問題,或有好提議,歡迎在公衆號「CodingAndroid」中提出