java - 如何在我的设置 Activity 中添加主题?

标签 java android sharedpreferences android-preferences

我正在创建一个支持多个主题的应用程序。当前的实现是用户可以从两个主题中选择一个主题并应用所选主题。

但现在我需要添加更多主题。我在 xml 文件中添加了一些主题。但我不知道如何在下面的Java文件中处理它。

所以请指导我。提前致谢!

Preferences.java

public class Preferences {

    private static final BoolToStringPref[] PREF_MIGRATION = new BoolToStringPref[]{
        new BoolToStringPref(R.string.pref_dark_theme, false,
                R.string.pref_theme, R.string.pref_theme_value_red),
};

    public static void sync(PreferenceManager preferenceManager) {
        Map<String, ?> map = preferenceManager.getSharedPreferences().getAll();
        for (String key : map.keySet()) {
            sync(preferenceManager, key);
        }
    }

    public static void sync(PreferenceManager preferenceManager, String key) {
        Preference pref = preferenceManager.findPreference(key);
        if (pref instanceof ListPreference) {
            ListPreference listPref = (ListPreference) pref;
            pref.setSummary(listPref.getEntry());
        }
    }

    /**
     * Migrate from boolean preferences to string preferences. Should be called only once
     * when application is relaunched.
     * If boolean preference has been set before, and value is not default, migrate to the new
     * corresponding string value
     * If boolean preference has been set before, but value is default, simply remove it
     * @param context   application context
     * TODO remove once all users migrated
     */
    public static void migrate(Context context) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = sp.edit();
        for (BoolToStringPref pref : PREF_MIGRATION) {
            if (pref.isChanged(context, sp)) {
                editor.putString(context.getString(pref.newKey), context.getString(pref.newValue));
            }

            if (pref.hasOldValue(context, sp)) {
                editor.remove(context.getString(pref.oldKey));
            }
        }

        editor.apply();
    }

    public static void applyTheme(ContextThemeWrapper contextThemeWrapper) {
        if (Preferences.darkThemeEnabled(contextThemeWrapper)) {
            contextThemeWrapper.setTheme(R.style.AppTheme_Blue);
        }
    }

    private static boolean darkThemeEnabled(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context)
                .getString(context.getString(R.string.pref_theme),
                        context.getString(R.string.pref_theme_value_red))
                .equals(context.getString(R.string.pref_theme_value_blue));
    }

    private static class BoolToStringPref {
        private final int oldKey;
        private final boolean oldDefault;
        private final int newKey;
        private final int newValue;

        private BoolToStringPref(@StringRes int oldKey, boolean oldDefault,
                                 @StringRes int newKey, @StringRes int newValue) {
            this.oldKey = oldKey;
            this.oldDefault = oldDefault;
            this.newKey = newKey;
            this.newValue = newValue;
        }

        private boolean isChanged(Context context, SharedPreferences sp) {
            return hasOldValue(context, sp) &&
                    sp.getBoolean(context.getString(oldKey), oldDefault) != oldDefault;
        }

        private boolean hasOldValue(Context context, SharedPreferences sp) {
            return sp.contains(context.getString(oldKey));
        }
    }
}

设置 Activity

    protected void onCreate(Bundle savedInstanceState) {
        Preferences.applyTheme(this);
        getDelegate().installViewFactory();
        getDelegate().onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        setToolbar();
        addPreferencesFromResource(R.xml.preferences);
        Preferences.sync(getPreferenceManager());
        mListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
                Preferences.sync(getPreferenceManager(), key);
                if (key.equals(getString(R.string.pref_theme))) {
                    finish();
                    final Intent intent = IntentCompat.makeMainActivity(new ComponentName(
                            SettingsActivity.this, MainActivity.class));
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                }
            }
        };
    }

最佳答案

这是一篇博客文章,概述了如何执行此操作(有可用的源代码)

http://www.hidroh.com/2015/02/25/support-multiple-themes-android-app-part-2/

这里是一个指南,向您展示如何通过用户输入(按下按钮等)以编程方式快速切换(上面扩展的 PreferenceFragment 可能更理想,但阅读下面的内容也可以提供丰富的信息)

http://www.developer.com/ws/android/changing-your-android-apps-theme-dynamically.html

关于java - 如何在我的设置 Activity 中添加主题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34446357/

相关文章:

android - 在使线性布局容器无效后未调用 subview 的 ondraw()

android - 使用 Jetpack Compose Navigation 时导航图是否已过时?

java - 如何通过 http 客户端执行 https get 请求?

java - 如何在Java中反序列化

java - Java 中静态同步方法到底是如何工作的?

java - ImageView 尺寸看起来比实际尺寸小

android - 在 Activity 之间使用共享偏好

Android SharedPreferences在多个进程之间不一致

android - 首选项管理器未从用户首选项中获取值(value)

java - 二叉树的层序遍历有哪些常见应用?