美文网首页
Android 多语言切换的一些bug与解决

Android 多语言切换的一些bug与解决

作者: zhaoyubetter | 来源:发表于2017-09-05 11:27 被阅读189次

    参考:

    1. http://www.lai18.com/content/6602031.html
    2. https://jaeger.itscoder.com/android/2016/05/14/switch-language-on-android-app.html
    3. http://gunhansancar.com/change-language-programmatically-in-android/

    具体设置可参考:
    https://jaeger.itscoder.com/android/2016/05/14/switch-language-on-android-app.html

    具体bug的产生,可参考:
    http://www.lai18.com/content/6602031.html

    解决方案

    如果代码中,没有基类,或者,不喜欢使用基类,可使用 activity生命周期callback来解决:

    工具类代码:

    public final class LocaleUtils {
    
        private static final String FILE_NAME = "better_language_info";
        private static final String KEY_LANGUAGE = "key_language";
        private static final String KEY_COUNTRY = "key_country";
    
        /**
         * 获取手机系统的Locale
         *
         * @return
         */
        public static Locale getSystemLocale() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                return LocaleList.getDefault().get(0);
            }
            return Locale.getDefault();
        }
    
        /**
         * 设置 App 的Locale
         *
         * @param context
         * @param loc
         * @return
         */
        public static void setAppLocale(Context context, Locale loc) {
            if (loc != null) {
                setUserSetLocale(context, loc);
    
                Resources rs = context.getResources();
                Configuration config = rs.getConfiguration();
                DisplayMetrics dm = rs.getDisplayMetrics();
                if (Build.VERSION.SDK_INT >= 17) {
                    config.setLocale(loc);
                } else {
                    config.locale = loc;
                }
                context.getResources().updateConfiguration(config, dm);
            }
        }
    
        /**
         * 在activity 的  onResume or onConfigChange中调用此方法
         * http://www.jianshu.com/p/47bbd34d2af8
         *
         * @param context
         * @param loc
         */
        public static void setLocaleWhenConfigChange(Context context, Locale loc) {
            if (loc != null) {
                Resources rs = context.getResources();
                Configuration config = rs.getConfiguration();
                DisplayMetrics dm = rs.getDisplayMetrics();
                if (Build.VERSION.SDK_INT >= 17) {
                    config.setLocale(loc);
                } else {
                    config.locale = loc;
                }
                context.getResources().updateConfiguration(config, dm);
            }
        }
    
        /**
         * 获取App Locale
         *
         * @param context
         * @return
         */
        public static Locale getAppLocale(Context context) {
            Configuration config = context.getResources().getConfiguration();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                return config.getLocales().get(0);
            else
                return config.locale;
        }
    
        /**
         * 获取用户设置的Locale
         *
         * @param context
         * @return
         */
        public static Locale getUserSetLocale(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
            String lang = sp.getString(KEY_LANGUAGE, "");
            String country = sp.getString(KEY_COUNTRY, "");
            if (!TextUtils.isEmpty(lang) && !TextUtils.isEmpty(country)) {
                return new Locale(lang, country);
            }
            return null;
        }
    
        /**
         * 返回 en_US 格式
         *
         * @param context
         * @return
         */
        public static String getUserSetLocaleStr(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
            String lang = sp.getString(KEY_LANGUAGE, "");
            String country = sp.getString(KEY_COUNTRY, "");
            if (!TextUtils.isEmpty(lang) && !TextUtils.isEmpty(country)) {
                return String.format("%s_%s", lang, country);
            }
            return "";
        }
    
        /**
         * 清空设置,跟随系统
         *
         * @param context
         */
        public static void removeLocaleSet(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
            final SharedPreferences.Editor edit = sp.edit();
            edit.putString(KEY_LANGUAGE, "");
            edit.putString(KEY_COUNTRY, "");
            edit.apply();
        }
    
        /**
         * 用户设置的Locale
         */
        private static void setUserSetLocale(Context context, Locale locale) {
            if (locale != null) {
                try {
                    SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
                    final SharedPreferences.Editor edit = sp.edit();
                    edit.putString(KEY_LANGUAGE, locale.getLanguage());
                    edit.putString(KEY_COUNTRY, locale.getCountry());
                    edit.apply();
                } catch (Exception e) {
                }
            }
        }
    }
    
    1. app 启动设置在 application 调用如下方法:
      private static void setLocale(Context context) {
            final Locale userSet = LocaleUtils.getUserSetLocale(context);
            if (userSet != null && LocaleUtils.getAppLocale(context) != userSet) {
                LocaleUtils.setAppLocale(context, userSet);
            }
        }
    
    1. 在 application类中,监听activity生命周期回调如下:
    private void registerLifeActivityCallbacks() {
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
    
                @Override
                public void onActivityResumed(Activity activity) {
                 
                    // 切换语言,修复bug
                    final Locale userSetLocale = LocaleUtils.getUserSetLocale(activity);
                    LocaleUtils.setLocaleWhenConfigChange(activity, userSetLocale);
                }
    

    这种bugs 也是头痛,难道 google允许某一个页面,是中文,另一个页面是英文这种么?

    相关文章

      网友评论

          本文标题:Android 多语言切换的一些bug与解决

          本文链接:https://www.haomeiwen.com/subject/dddujxtx.html