Android實現多語言so easy

微信公衆號:CodingAndroid
CSDN:blog.csdn.net/xinpengfei5…
聲明:本文由CodingAndroid原創,未經受權,不可隨意轉載!css

      最近,咱們公司的業務已經拓展到了香港,咱們都知道香港使用的是繁體中文,所以,咱們的APP要能夠設置繁體語言,這不咱們要緊跟國際的步伐,實現多語言,產品定給咱們的需求主要以實現簡體中文、繁體中文、英文三種語言切換便可,具體的業務邏輯是:當用戶第一次進入APP時,App的語言跟隨當前系統語言,當用戶設置了某種語言以後就切換爲用戶設置的語言,無論系統以後設置成哪一種語言,都不會影響用戶設置的語言,若是用戶一直沒有設置語言選項,只要系統語言改變時,APP的語言也要跟隨系統語言設置改變。java

      說明:本文以實現簡體中文、繁體中文和英語爲例進行簡要講解。android

1.實現思路

      咱們能夠預先使用SharedPreference來保存一個語言類型的值,當用戶第一次進入APP時,咱們經過Key取出這個值,第一次確定是取不到的,這時咱們將App的語言設置爲當前系統默認值便可;當用戶通設置多語言時,咱們將這個語言對應的值經過SharedPreference保存到本地便可,而後此時重啓APP,設置爲用戶設置的語言便可,之後每次進入App時只需取出保存用戶設置的語言設置便可,通常設置語言寫在程序的入口 ApplicationonCreate() 方法裏。git

2.自定義SharedPreference工具類

      做用:用於保存當前設置語言的類型,此文以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();
}
}
複製代碼

3.自定義LocaleUtil工具類

      做用:用於設置保存語言及獲取當前語言,重啓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());
}
}
}
複製代碼

3.1Application中調用,用於初始化語言設置

@Override
public void onCreate() {
super.onCreate();
LocaleUtil.changeAppLanguage(this);
}
複製代碼

3.2在Application中重寫以下方法:用於當系統設置語言變化時進行語言設置

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.e("TAG", "onConfigurationChanged");
LocaleUtil.setLanguage(mContext, newConfig);
}
複製代碼

3.3在多語言設置界面設置APP語言

      當用戶點擊保存時傳入當前語言對應的Index值便可,我這裏使用的是保存一個Int類型的值,每個Int類型的值對應一種語言的類型,固然你能夠根據本身的實現保存爲String類型也是能夠的。微信

LocaleUtil.changeAppLanguage(mContext, currentLanguage);
複製代碼

4.多國語言文件夾命名對應表以下:

      本文只以簡體中文、繁體中文和英語爲例,要想實現更多語言設置,請參考下表: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

5.常見的一些坑

  • 設置英文語言時在有些手機上不起做用
    在開發過程當中咱們試過在Redmi Note 4手機上設置英語語言不起做用,這是因爲有些手機廠商的默認英語設置的是英式英語,而咱們只使用了美式英語的緣故,此時處理方式爲:①設置兩種英語的設置選項,即美式英語和英式英語;②可將res的文件夾命名爲values-en便可,不區分英式英語和美式英語便可;
  • 在Android Studio3.0以前,若是有些strings沒有對應到其餘的語種,即有些字段沒有翻譯過來,打包時會 報警告,能夠打成包,而3.0以後是不能夠的,會打包失敗,因此每一個Strings必須對應一套完整的翻譯!

6.相關權限

<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
複製代碼

7.更多探討

      在實現APP種切換語言時,試了試微信的多語言設置頁面是在4級頁面,當它設置完語言以後先是跳轉到 界面(一級頁面),而後緊接着跳到設置界面(二級頁面),貌似微信沒有重啓App,它只是管理保存了Activity任務棧,最後跳轉到設置界面,而個人例子只是重啓了App沒有跳轉回到設置界面,固然這要看具體的需求了,我我的感受,設置完就沒有必要再跳轉回去了。ide


最後附上Demo:
github.com/xinpengfei5…工具

若是你以爲不錯能夠幫我點個star,3Q~

若在使用過程當中遇到什麼問題,或有好提議,歡迎在公衆號「CodingAndroid」中提出
這裏寫圖片描述

相關文章
相關標籤/搜索