解决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