起因
我們?cè)陂_發(fā)app可能會(huì)拓展國外市場(chǎng),那么對(duì)包含英語在內(nèi)的其它語言支持就很有必要了。
效果
思路
一:添加相關(guān)資源文件,并引用。
二:設(shè)置configuration,configuration里面指定語言類型。
三:在需要時(shí)候更換configuration即可。
實(shí)現(xiàn)
在res的values文件夾下新建相關(guān)語言類型的資源文件
右鍵新建資源文件,選擇Locale,點(diǎn)擊 >> 按鈕
選擇Language,以及地區(qū)(any region)即可
最后 文件名字和其他語言文件名字一樣,strings即可。
在MyApplication里面的onCreate和onConfigurationChanged方法里面添加語言相關(guān)處理(onConfigurationChanged是為了處理橫豎屏切換問題),給應(yīng)用上下文對(duì)象添加configuration,configuration里面指定了當(dāng)前語言。
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,在之后啟動(dòng)應(yīng)用依舊使用B語言,我們需要將B語言存入本地。下次啟動(dòng)應(yīng)用,設(shè)置即可。
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; 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)前語言選擇activity)的所有activity進(jìn)行recreate(),即可。languageUtil同時(shí)進(jìn)行了是否需要切換語言的判定。如果當(dāng)前語言和要選擇的一致,則無需再做處理)
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; } /** * 單一實(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 ; } } } //獲取指定類名的Activity public 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)行。
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變動(dòng)而已,跟著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設(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í)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.jianshu.com/p/b9e32fad36a2