解決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地址

MultiLanguagesSwitch

轉自: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.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM