解决Android 7.0 App内切换语言不生效的问题
Android7.0及以前版本,Configuration中的语言相当于是App的全局设置:
1 public static void changeAppLanguage(Context context, String newLanguage){
2 Resources resources = context.getResources();
3 Configuration configuration = resources.getConfiguration();
4
5 // app locale
6 Locale locale = getLocaleByLanguage(newLanguage);
7
8 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
9 configuration.setLocale(locale);
10 } else {
11 configuration.locale = locale;
12 }
13
14 // updateConfiguration
15 DisplayMetrics dm = resources.getDisplayMetrics();
16 resources.updateConfiguration(configuration, dm);
17 }
然后在继承application的类中调用即可:
1 public class App extends Application {
2
3 @Override
4 public void onCreate() {
5 super.onCreate();
6 onLanguageChange();
7 }
8
9 /**
10 * Handling Configuration Changes
11 * @param newConfig newConfig
12 */
13 @Override
14 public void onConfigurationChanged(Configuration newConfig) {
15 super.onConfigurationChanged(newConfig);
16 onLanguageChange();
17 }
18
19 private void onLanguageChange() {
20 String language;//读取App配置
21 AppLanguageUtils.changeAppLanguage(this, language);
22 }
23 }
Android7.0及之后版本,使用了LocaleList,Configuration中的语言设置可能获取的不同,而是生效于各自的Context。
这会导致:Android7.0使用就的方式,有些Activity可能会显示为手机的系统语言。
Android7.0 优化了对多语言的支持,废弃了updateConfiguration()方法,替代方法:createConfigurationContext(), 而返回的是Context。
也就是语言需要植入到Context中,每个Context都植入一遍。
GitHub地址
转自:https://yanlu.me/android-7-0-app-language-switch/
我自己的使用方式如下:
1.创建工具类
1 public class AppLanguageUtils {
2
3 public static HashMap<String, Locale> mAllLanguages = new HashMap<String, Locale>(8) {{
4 put(Constants.ENGLISH, Locale.ENGLISH);
5 put(Constants.CHINESE, Locale.SIMPLIFIED_CHINESE);
6 put(Constants.SIMPLIFIED_CHINESE, Locale.SIMPLIFIED_CHINESE);
7 put(Constants.TRADITIONAL_CHINESE, Locale.TRADITIONAL_CHINESE);
8 put(Constants.FRANCE, Locale.FRANCE);
9 put(Constants.GERMAN, Locale.GERMANY);
10 put(Constants.HINDI, new Locale(Constants.HINDI, "IN"));
11 put(Constants.ITALIAN, Locale.ITALY);
12 }};
13
14 @SuppressWarnings("deprecation")
15 public static void changeAppLanguage(Context context, String newLanguage) {
16 Resources resources = context.getResources();
17 Configuration configuration = resources.getConfiguration();
18
19 // app locale
20 Locale locale = getLocaleByLanguage(newLanguage);
21
22 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
23 configuration.setLocale(locale);
24 } else {
25 configuration.locale = locale;
26 }
27
28 // updateConfiguration
29 DisplayMetrics dm = resources.getDisplayMetrics();
30 resources.updateConfiguration(configuration, dm);
31 }
32
33
34 private static boolean isSupportLanguage(String language) {
35 return mAllLanguages.containsKey(language);
36 }
37
38 public static String getSupportLanguage(String language) {
39 if (isSupportLanguage(language)) {
40 return language;
41 }
42
43 if (null == language) {//为空则表示首次安装或未选择过语言,获取系统默认语言
44 Locale locale = Locale.getDefault();
45 for (String key : mAllLanguages.keySet()) {
46 if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
47 return locale.getLanguage();
48 }
49 }
50 }
51 return Constants.ENGLISH;
52 }
53
54 /**
55 * 获取指定语言的locale信息,如果指定语言不存在{@link #mAllLanguages},返回本机语言,如果本机语言不是语言集合中的一种{@link #mAllLanguages},返回英语
56 *
57 * @param language language
58 * @return
59 */
60 public static Locale getLocaleByLanguage(String language) {
61 if (isSupportLanguage(language)) {
62 return mAllLanguages.get(language);
63 } else {
64 Locale locale = Locale.getDefault();
65 for (String key : mAllLanguages.keySet()) {
66 if (TextUtils.equals(mAllLanguages.get(key).getLanguage(), locale.getLanguage())) {
67 return locale;
68 }
69 }
70 }
71 return Locale.ENGLISH;
72 }
73
74
75 public static Context attachBaseContext(Context context, String language) {
76 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
77 return updateResources(context, language);
78 } else {
79 return context;
80 }
81 }
82
83
84 @TargetApi(Build.VERSION_CODES.N)
85 private static Context updateResources(Context context, String language) {
86 Resources resources = context.getResources();
87 Locale locale = AppLanguageUtils.getLocaleByLanguage(language);
88
89 Configuration configuration = resources.getConfiguration();
90 configuration.setLocale(locale);
91 configuration.setLocales(new LocaleList(locale));
92 return context.createConfigurationContext(configuration);
93 }
94
95 }
2.在继承application的类中重写attachBaseContext()方法等操作
1 private static Context sContext;
2 private String language;
3
4 @Override
5 protected void attachBaseContext(Context base) {
6 super.attachBaseContext(AppLanguageUtils.attachBaseContext(base, getAppLanguage(base)));
7 }
8
9 @Override
10 public void onCreate() {
11 super.onCreate();
12 sContext = this;
13 spu = new SharedPreferencesUtil(getApplicationContext());
14 language = spu.getString("language");
15 onLanguageChange();
16 }
17
18 public static Context getContext() {
19 return sContext;
20 }
21
22 /**
23 * Handling Configuration Changes
24 * @param newConfig newConfig
25 */
26 @Override
27 public void onConfigurationChanged(Configuration newConfig) {
28 super.onConfigurationChanged(newConfig);
29 onLanguageChange();
30 }
31
32 private void onLanguageChange() {
33 // AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(getAppLanguage(this)));
34 AppLanguageUtils.changeAppLanguage(this, AppLanguageUtils.getSupportLanguage(language));
35 }
36
37 private String getAppLanguage(Context context) {
38 String appLang = PreferenceManager.getDefaultSharedPreferences(context)
39 .getString("language", Constants.ENGLISH);
40 return appLang ;
41 }
3.在需要切换语言的SetLanguageActivity中设置切换方法
private void onChangeAppLanguage(String newLanguage) {
spu.putString("language", newLanguage);
AppLanguageUtils.changeAppLanguage(this, newLanguage);
AppLanguageUtils.changeAppLanguage(App.getContext(), newLanguage);
this.recreate();
}
4.跳转到SetLanguageActivity的原界面语言需要刷新
//携参跳转
startActivityForResult(new Intent(OriginActivity.this, SetLanguageActivity.class), CHANGE_LANGUAGE_REQUEST_CODE);
//切换后返回刷新
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CHANGE_LANGUAGE_REQUEST_CODE) {
recreate();
}
}
That's all.