重写onAttachBaseContext时未调用onConfigurationChanged的自定义视图

时间:2017-11-24 19:16:15

标签: android setlocale

我在onAttachBaseContext()覆盖Activity以传递最新的语言环境。但在执行此操作后,我观察到我在Activity类中的自定义视图不再调用onConfigurationChanged()关于更改方向。只有Activity onConfigurationChanged()才能接听电话。有没有办法纠正这个? (我不想将事件从Activity传递到自定义视图以进行方向更改)

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(LocaleHelper.setLanguage(newBase));
}

LocaleHelper:

public class LocaleHelper extends ContextWrapper {

public LocaleHelper(Context base) {
    super(base);
}

public static Context setLanguage(Context context) {
    String currentLanguage = getLanguage(context);
    context = setLocale(context, currentLanguage);
    return new LocaleHelper(context);
}

public static Context setLocale(Context context, String language) {
    persist(context, language);
    return updateResources(context, language);
}


private static void persist(Context context, String language) {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();
    Logger.log(TAG, "persist: "+language);
    editor.putString(SELECTED_LANGUAGE, language);
    editor.apply();
}

private static Context updateResources(Context context, String language) {
    Locale locale = new Locale(language);
    Logger.log(TAG, "updateResources: "+language);

    Resources resources = context.getResources();
    Configuration config = resources.getConfiguration();
    if (isAtleastNougat()) {
        config.setLocale(locale);
        LocaleList localeList = new LocaleList(locale);
        LocaleList.setDefault(localeList);
        config.setLocales(localeList);
        context = context.createConfigurationContext(config);
    }
    else if (isAtleastAPI17()) {
        config.setLocale(locale);
        context = context.createConfigurationContext(config);
    } else {
        config.locale = locale;
        resources.updateConfiguration(config, resources.getDisplayMetrics());
    }
    return context;

}

1 个答案:

答案 0 :(得分:3)

不要使用updateResources函数。替换为此类中的函数:

public class MyContextWrapper extends ContextWrapper {

    public MyContextWrapper(Context base) {
        super(base);
    }

    @SuppressWarnings("deprecation")
    public static ContextWrapper wrap(Context context, String language) {
        Configuration config = context.getResources().getConfiguration();
        Locale sysLocale = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sysLocale = getSystemLocale(config);
        } else {
            sysLocale = getSystemLocaleLegacy(config);
        }
        if (!language.equals("") && !sysLocale.getLanguage().equals(language)) {
            Locale locale = new Locale(language);
            Locale.setDefault(locale);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                setSystemLocale(config, locale);
            } else {
                setSystemLocaleLegacy(config, locale);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                context = context.createConfigurationContext(config);
            } else {
                context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
            }
        }
        return new MyContextWrapper(context);
    }

    @SuppressWarnings("deprecation")
    public static Locale getSystemLocaleLegacy(Configuration config){
        return config.locale;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static Locale getSystemLocale(Configuration config){
        return config.getLocales().get(0);
    }

    @SuppressWarnings("deprecation")
    public static void setSystemLocaleLegacy(Configuration config, Locale locale){
        config.locale = locale;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static void setSystemLocale(Configuration config, Locale locale){
        config.setLocale(locale);
    }
}