一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android支持國際化多語言那點事(支持8.0+)

Android支持國際化多語言那點事(支持8.0+)

2022-02-28 15:15Allen___ Android

我們在開發app可能會拓展國外市場,那么對包含英語在內的其它語言支持就很有必要了。這篇文章主要介紹了Android支持國際化多語言那點事(支持8.0+),具有一定的參考價值,感興趣的小伙伴們可以參考一下

起因

我們在開發app可能會拓展國外市場,那么對包含英語在內的其它語言支持就很有必要了。

效果

Android支持國際化多語言那點事(支持8.0+)

思路

一:添加相關資源文件,并引用。
二:設置configuration,configuration里面指定語言類型。
三:在需要時候更換configuration即可。

實現

在res的values文件夾下新建相關語言類型的資源文件

右鍵新建資源文件,選擇Locale,點擊 >> 按鈕

Android支持國際化多語言那點事(支持8.0+)

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

Android支持國際化多語言那點事(支持8.0+)

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

在MyApplication里面的onCreate和onConfigurationChanged方法里面添加語言相關處理(onConfigurationChanged是為了處理橫豎屏切換問題),給應用上下文對象添加configuration,configuration里面指定了當前語言。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyApplication extends Application {
@Override
public void onCreate() {
  super.onCreate();
  languageWork();
}
 
@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  languageWork();
}
 
private void languageWork() {
  //自己寫的工具包(如下)
  Locale locale = LanguageUtil.getLocale(this);
  LanguageUtil.updateLocale(this, locale);
}
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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有多語言設置獲取頂部的語言
    locale = context.getResources().getConfiguration().getLocales().get(0);
  } else {
    locale = context.getResources().getConfiguration().locale;
  }
  return locale;
}
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class ActivityManager {
private static final Stack<Activity> sActivityStack = new Stack<>();
private static ActivityManager sActivityManager;
 
private ActivityManager() {
}
 
public Stack<Activity> getActivityStack() {
  return sActivityStack;
}
 
/**
 * 單一實例
 */
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);
}
 
/**
 * 獲取當前Activity(堆棧中最后一個壓入的)
 */
public Activity currentActivity() {
 
  Activity activity = sActivityStack.lastElement();
  return activity;
}
 
/**
 * 結束當前Activity(堆棧中最后一個壓入的)
 */
public void finishActivity() {
  Activity activity = sActivityStack.lastElement();
  finishActivity(activity);
}
 
/**
 * 結束指定的Activity
 */
public void finishActivity(Activity activity) {
  if (activity != null) {
    sActivityStack.remove(activity);
    activity.finish();
  }
}
 
/**
 * 結束指定類名的Activity
 */
public void finishActivity(Class<?> cls) {
  for (Activity activity : sActivityStack) {
    if (activity.getClass().equals(cls)) {
      finishActivity(activity);
      return;
    }
  }
 
}
 
//獲取指定類名的Activity
public Activity getActivity(Class<?> cls) {
  for (Activity activity : sActivityStack) {
    if (activity.getClass().equals(cls)) {
      return activity;
    }
  }
  return null;
}
 
/**
 * 結束所有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();
    }
  }
}
 
/**
 * 退出應用程序
 */
public void AppExit() {
  try {
    finishAllActivity();
    System.exit(0);
  } catch (Exception e) {
  }
  }
  }

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

?
1
2
3
4
5
6
7
8
9
10
11
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  ActivityManager.getInstance().addActivity(this);
}
 
@Override
protected void onDestroy() {
  super.onDestroy();
  ActivityManager.getInstance().removeActivity(this);
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override
protected void attachBaseContext(Context newBase) {
  Context context = languageWork(newBase);
  super.attachBaseContext(context);
 
 }
 
private Context languageWork(Context context) {
  // 8.0及以上使用createConfigurationContext設置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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.jianshu.com/p/b9e32fad36a2

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久91精品国产一区二区 | 香蕉成人国产精品免费看网站 | 亚洲第一色网站 | 亚洲成a人不卡在线观看 | 9420高清完整版在线观看国语 | 无码一区二区三区视频 | 国产成人盗拍精品免费视频 | 免费国产影视观看网站入口 | 国产日韩精品一区二区在线观看 | 国产91精品区 | 欧美18一19性高清hd4k | xxx美国| 色天天综合色天天看 | 日韩基地1024首页 | 亚洲视频免费在线看 | 欧美日韩国产精品自在自线 | 欧美大陆日韩一区二区三区 | 国产亚洲高清国产拍精品 | 美女逼逼软件 | 色哟哟在线视频 | 精品国产乱码久久久久久软件 | 亚洲国产自拍在线 | 国产免费丝袜调教视频 | 国产一区二区精品久 | fuqer日本老师 | 女老板用丝袜脚夹我好爽 | 久久受www免费人成_看片中文 | 红楼影视h38bar在线线播放 | 免费精品视频在线 | 日日操日日 | 国内精品 大秀视频 日韩精品 | 日韩精品欧美高清区 | 精品久久久噜噜噜久久久app | 日韩日韩日韩手机看片自拍 | 大学生特黄特色大片免费播放 | 国产高清视频 | 无限资源在线观看播放 | 亚洲女性色尼古综合网 | 嗯啊好大好爽 | 99午夜高清在线视频在观看 | 国产成人夜色影视视频 |