国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android支持國(guó)際化多語(yǔ)言那點(diǎn)事(支持8.0+)

2019-10-22 18:10:17
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

起因

我們?cè)陂_(kāi)發(fā)app可能會(huì)拓展國(guó)外市場(chǎng),那么對(duì)包含英語(yǔ)在內(nèi)的其它語(yǔ)言支持就很有必要了。

效果

Android,國(guó)際化,多語(yǔ)言

思路

一:添加相關(guān)資源文件,并引用。
二:設(shè)置configuration,configuration里面指定語(yǔ)言類型。
三:在需要時(shí)候更換configuration即可。

實(shí)現(xiàn)

在res的values文件夾下新建相關(guān)語(yǔ)言類型的資源文件

右鍵新建資源文件,選擇Locale,點(diǎn)擊 >> 按鈕

Android,國(guó)際化,多語(yǔ)言

選擇Language,以及地區(qū)(any region)即可

Android,國(guó)際化,多語(yǔ)言

最后 文件名字和其他語(yǔ)言文件名字一樣,strings即可。

在MyApplication里面的onCreate和onConfigurationChanged方法里面添加語(yǔ)言相關(guān)處理(onConfigurationChanged是為了處理橫豎屏切換問(wèn)題),給應(yīng)用上下文對(duì)象添加configuration,configuration里面指定了當(dāng)前語(yǔ)言。

public class MyApplication extends Application {@Overridepublic void onCreate() {  super.onCreate();  languageWork();}@Overridepublic void onConfigurationChanged(Configuration newConfig) {  super.onConfigurationChanged(newConfig);  languageWork();}private void languageWork() {  //自己寫的工具包(如下)  Locale locale = LanguageUtil.getLocale(this);  LanguageUtil.updateLocale(this, locale);}}

LanguageUtil如下(沒(méi)整理過(guò)的小伙伴直接用即可),為了保證語(yǔ)言從A切換到B,在之后啟動(dòng)應(yīng)用依舊使用B語(yǔ)言,我們需要將B語(yǔ)言存入本地。下次啟動(dòng)應(yīng)用,設(shè)置即可。

public class LanguageUtil {/** * 中文 */public static final Locale LOCALE_CHINESE = Locale.CHINESE;/** * 英文 */public static final Locale LOCALE_ENGLISH = Locale.ENGLISH;/** * 俄文 */public static final Locale LOCALE_RUSSIAN = new Locale("ru");private static final String LOCALE_SP = "LOCALE_SP";private static final String LOCALE_SP_KEY = "LOCALE_SP_KEY"; public static Locale getLocale(Context context) {  SharedPreferences spLocale = context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE);  String localeJson = spLocale.getString(LOCALE_SP_KEY, "");  Gson gson = new Gson();  return gson.fromJson(localeJson, Locale.class);}pivate static void setLocale(Context pContext, Locale pUserLocale) {  SharedPreferences spLocal = pContext.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE);  SharedPreferences.Editor edit = spLocal.edit();  String json = new Gson().toJson(pUserLocale);  edit.putString(LOCALE_SP_KEY, json);  edit.apply();}public static boolean updateLocale(Context context, Locale locale) {  if (needUpdateLocale(context, locale)) {    Configuration configuration = context.getResources().getConfiguration();    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {      configuration.setLocale(locale);    } else {      configuration.locale = locale;    }    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    context.getResources().updateConfiguration(configuration, displayMetrics);    setLocale(context, locale);    return true;  }  return false;}public static boolean needUpdateLocale(Context pContext, Locale newUserLocale) {  return newUserLocale != null && !getCurrentLocale(pContext).equals(newUserLocale);}public static Locale getCurrentLocale(Context context) {  Locale locale;  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //7.0有多語(yǔ)言設(shè)置獲取頂部的語(yǔ)言    locale = context.getResources().getConfiguration().getLocales().get(0);  } else {    locale = context.getResources().getConfiguration().locale;  }  return locale;}}

進(jìn)行切換,主要觸發(fā)動(dòng)作是activity的recreate()(切換使用新的configuration)。所有的activity在activityManager里面進(jìn)行管理。只需將其他(除了當(dāng)前語(yǔ)言選擇activity)的所有activity進(jìn)行recreate(),即可。languageUtil同時(shí)進(jìn)行了是否需要切換語(yǔ)言的判定。如果當(dāng)前語(yǔ)言和要選擇的一致,則無(wú)需再做處理)

 public void onClick(View view) {  boolean need = false;  switch (view.getId()) {    case R.id.chinese:      need = LanguageUtil.updateLocale(this, LanguageUtil.LOCALE_CHINESE);      if (need) {        //自己寫的常用activity管理工具        ActivityManager.getInstance().recreateAllOtherActivity(this);        Toast.makeText(this, "change to chinese", Toast.LENGTH_SHORT).show();      } else {        Toast.makeText(this, "no need", Toast.LENGTH_SHORT).show();      }      break;    case R.id.english:      need = LanguageUtil.updateLocale(this, LanguageUtil.LOCALE_ENGLISH);      if (need) {        ActivityManager.getInstance().recreateAllOtherActivity(this);        Toast.makeText(this, "change to english", Toast.LENGTH_SHORT).show();      } else {        Toast.makeText(this, "no need", Toast.LENGTH_SHORT).show();      }      break;    case R.id.russian:      need = LanguageUtil.updateLocale(this, LanguageUtil.LOCALE_RUSSIAN);      if (need) {        ActivityManager.getInstance().recreateAllOtherActivity(this);        Toast.makeText(this, "change to russian", Toast.LENGTH_SHORT).show();      } else {        Toast.makeText(this, "no need", Toast.LENGTH_SHORT).show();      }      break;  }}

ActivityManager如下

 public class ActivityManager {private static final Stack<Activity> sActivityStack = new Stack<>();private static ActivityManager sActivityManager;private ActivityManager() {}public Stack<Activity> getActivityStack() {  return sActivityStack;}/** * 單一實(shí)例 */public static ActivityManager getInstance() {  if (sActivityManager == null) {    synchronized (ActivityManager.class) {      sActivityManager = new ActivityManager();    }  }  return sActivityManager;}/** * 添加Activity到堆棧 */public void addActivity(Activity activity) {  sActivityStack.add(activity);}/** * 刪除堆棧中的Activity */public void removeActivity(Activity activity) {  if (sActivityStack.isEmpty()) {    return;  }  sActivityStack.remove(activity);}/** * 獲取當(dāng)前Activity(堆棧中最后一個(gè)壓入的) */public Activity currentActivity() {  Activity activity = sActivityStack.lastElement();  return activity;}/** * 結(jié)束當(dāng)前Activity(堆棧中最后一個(gè)壓入的) */public void finishActivity() {  Activity activity = sActivityStack.lastElement();  finishActivity(activity);}/** * 結(jié)束指定的Activity */public void finishActivity(Activity activity) {  if (activity != null) {    sActivityStack.remove(activity);    activity.finish();  }}/** * 結(jié)束指定類名的Activity */public void finishActivity(Class<?> cls) {  for (Activity activity : sActivityStack) {    if (activity.getClass().equals(cls)) {      finishActivity(activity);      return;    }  }}//獲取指定類名的Activitypublic Activity getActivity(Class<?> cls) {  for (Activity activity : sActivityStack) {    if (activity.getClass().equals(cls)) {      return activity;    }  }  return null;}/** * 結(jié)束所有Activity */public void finishAllActivity() {  for (int i = 0, size = sActivityStack.size(); i < size; i++) {    if (null != sActivityStack.get(i)) {      sActivityStack.get(i).finish();    }  }  sActivityStack.clear();}public void finishAllOtherActivity(Activity activity) {  for (int i = 0, size = sActivityStack.size(); i < size; i++) {    if (null != sActivityStack.get(i) && sActivityStack.get(i) != activity) {      sActivityStack.get(i).finish();    }  }  sActivityStack.clear();}public void recreateAllOtherActivity(Activity activity) {  for (int i = 0, size = sActivityStack.size(); i < size; i++) {    if (null != sActivityStack.get(i) && sActivityStack.get(i) != activity) {      sActivityStack.get(i).recreate();    }  }}/** * 退出應(yīng)用程序 */public void AppExit() {  try {    finishAllActivity();    System.exit(0);  } catch (Exception e) {  }  }  }

將app的所有acitivity進(jìn)行添加和移除,可以在BaseActivity里面進(jìn)行。

@Overrideprotected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  ActivityManager.getInstance().addActivity(this);}@Overrideprotected void onDestroy() {  super.onDestroy();  ActivityManager.getInstance().removeActivity(this);}

以上步驟,我們的語(yǔ)言切換算是完成了。但是,在API 26+以上版本,我們需要額外添加如下代碼做兼容,沒(méi)啥說(shuō)的,SDK變動(dòng)而已,跟著SDK走咯~(在activity或者BaseActivity添加)

 @Overrideprotected void attachBaseContext(Context newBase) {  Context context = languageWork(newBase);  super.attachBaseContext(context); }private Context languageWork(Context context) {  // 8.0及以上使用createConfigurationContext設(shè)置configuration  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {    return updateResources(context);  } else {    return context;  }  }@RequiresApi(api = Build.VERSION_CODES.O)private Context updateResources(Context context) {  Resources resources = context.getResources();  Locale locale = LanguageUtil.getLocale(context);  if (locale==null) {    return context;  }  Configuration configuration = resources.getConfiguration();  configuration.setLocale(locale);  configuration.setLocales(new LocaleList(locale));  return context.createConfigurationContext(configuration);  }

完工~

地址:https://github.com/HoldMyOwn/MultiLanguage

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 湛江市| 濉溪县| 抚宁县| 怀安县| 剑河县| 抚州市| 宜黄县| 延川县| 苍南县| 庐江县| 邵武市| 宽城| 阳东县| 灌云县| 鄯善县| 罗平县| 延寿县| 从化市| 从江县| 新邵县| 门头沟区| 益阳市| 通州区| 崇明县| 金沙县| 宁陕县| 太白县| 慈溪市| 云南省| 突泉县| 渭南市| 额尔古纳市| 长顺县| 饶河县| 清丰县| 磐安县| 南雄市| 阿勒泰市| 五华县| 亚东县| 稷山县|