解決Android 7.0 App內切換語言不生效的問題

Android7.0及之前版本,Configuration中的語言至關因而App的全局設置:android

 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的類中調用便可:git

 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。github

這會致使:Android7.0使用就的方式,有些Activity可能會顯示爲手機的系統語言。app

Android7.0 優化了對多語言的支持,廢棄了updateConfiguration()方法,替代方法:createConfigurationContext(), 而返回的是Context。ide

也就是語言須要植入到Context中,每一個Context都植入一遍。工具

GitHub地址

MultiLanguagesSwitch優化

轉自:https://yanlu.me/android-7-0-app-language-switch/ui

 

我本身的使用方式以下:this

1.建立工具類spa

 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.

相關文章
相關標籤/搜索