zoukankan      html  css  js  c++  java
  • 解决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.

     

  • 相关阅读:
    【POJ 2778】DNA Sequence
    【POJ 2923】Relocation
    codeforces 475D
    hdu4742
    hdu4741
    hdu5016
    poj3929
    Codeforces Round #267 (Div. 2)
    codeforces 455E
    hdu4073 Lights
  • 原文地址:https://www.cnblogs.com/Sharley/p/9155824.html
Copyright © 2011-2022 走看看