如何更新我的项目创建一个多主题应用程序

时间:2016-07-29 22:19:08

标签: android themes

我想让SettingsActivity让用户个性化应用的外观。 在此活动中,用户可以选择将应用程序保持在“灯光主题”(这意味着例如带有黑色文本的白色背景)或“黑暗主题”,浅色主题的相反颜色有利于夜间使用。

怎么可能呢?

我正在考虑为每个主题在xml中创建不同的布局。

EDITS

以下图片是SettingsActivity的示例,我想更改整个应用的外观,而不是单个活动。

enter image description here

enter image description here

enter image description here

enter image description here

4 个答案:

答案 0 :(得分:3)

您可以创建自己的主题,然后当用户想要更改它们时,将此代码添加到您的活动中,您可以选择您想要的任何主题,而不仅仅是Holo。

getApplication()。setTheme(Theme.Holo)

答案 1 :(得分:3)

也许这个答案可以帮助你解决这个问题 https://stackoverflow.com/a/4673209/4858673

public class BaseActivity extends Activity {

    protected void onCreate(Bundle state) {
        super.onCreate(state);
        String theme = PreferenceManager.getDefaultSharedPreferences(this).getString("theme", "black");
        setTheme(getTheme(theme);
    }

    private int getTheme(String theme) {
        if (theme.equals("black") return R.style.ThemeBlack;
        if (theme.equals("white") return R.style.ThemeWhite;
        ...
        return android.R.style.Theme; // stub
    }
}

并从此BaseActivity扩展您的所有活动。如果要使用PreferenceActivity或PreferenceFragment,请将此代码放入实现中,这样您只能扩展一个类 - Activity(AppCompatActivity)或PreferenceActivity

P.S。 R.style.ThemeBlack是styles.xml中的主题设置

<style name="ThemeBlack" parent="android:Theme.Holo">
</style>

答案 2 :(得分:3)

这就是我为我的应用做的。我确信我的方法可以提供帮助。

styles.xml 中设置您的Light和Dark主题,如下所示:

     <!-- Use this theme in Manifest by default -->
    <style name="MyLightTheme" parent="Base.AppTheme.Light"></style>
    
    <!-- Base light theme containing all styles -->
    <style name="Base.AppTheme.Light" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        ... Other styles
    </style>

    <!-- Use this to switch to Dark theme -->
    <style name="MyDarkTheme" parent="Base.AppTheme.Dark"></style>

    <!-- Base dark theme containing all styles -->
    <style name="Base.AppTheme.Dark" parent="Theme.AppCompat">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        ... Other styles
    </style>

由于您通过偏好设置控制主题更改,请在 PreferenceFragment 中注册偏好更改侦听器。

PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(this);

实施 onSharedPreferenceChanged()

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        if (key.equals(getString(R.string.pref_key_nighttheme))) {

            if (sharedPreferences.getBoolean(getString(R.string.pref_key_nighttheme), false)) {
                //  Night theme enabled

                getActivity().setTheme(R.style.MyDarkTheme);  
                       getActivity().getApplication().setTheme(R.style.MyDarkTheme);
               darkTheme = true;

            } else {
                getActivity().setTheme(R.style.MyLightTheme);
                getActivity().getApplication().setTheme(R.style.MyLightTheme);
               darkTheme = false;
            }

            getActivity().recreate(); // This is important. It allows the theme change to take effect.
        } 
    }

如果返回导航导致MainActivity,请务必在 onResume()中重新创建 MainActivity

此外,您必须在 onCreate()中调用 super()之前检查每个活动中的当前主题。

  isThemeDark = setDarkTheme(this);

setDarkTheme()是我创建的帮助程序,它通过 SharedPreference 检查当前主题。它会检查是否有必要更改主题。

    public static boolean setDarkTheme(Context context) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

    boolean isDarkTheme = prefs.getBoolean(context.getString(R.string.pref_key_nighttheme), false);
    context.setTheme(SettingsActivity.darkTheme ? R.style.MyDarkTheme : R.style.MyLightTheme);

    return isDarkTheme;
}

以下是我的应用Newslet中夜间模式的工作原理:

enter image description here

<强>更新 Android现在通过其AppCompat DayNight主题正式支持夜间模式。 这是一个tutorial

答案 3 :(得分:0)

  1. 首先,您需要在xml-styles中创建一些定义良好的主题。

    <style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/primaryColorAmber</item>
        <item name="colorPrimaryDark">@color/primaryDarkColorAmber</item>
        <item name="colorAccent">@color/secondaryColorAmber</item>
    </style>
    
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    
    <style name="AppTheme.RED" parent="AppTheme.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/primaryColorRed</item>
        <item name="colorPrimaryDark">@color/primaryDarkColorRed</item>
        <item name="colorAccent">@color/secondaryColorRed</item>
    </style>
    
    <style name="AppTheme.PINK" parent="AppTheme.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/primaryColorPink</item>
        <item name="colorPrimaryDark">@color/primaryDarkColorPink</item>
        <item name="colorAccent">@color/secondaryColorPink</item>
    </style>
    
  2. 要在运行时更改主题,请在基本活动onCreate()方法中使用以下代码,并在setContentView()之前使用。

    //要更改主题,只需输入您的主题ID。

    int theme = getThemeFromPreferences(); // R.style.AppTheme_RED
    setTheme(theme);
    
  3. 要更改设置/首选项活动的主题(您要更改主题的位置),您需要通过调用该活动的以下方法来重新创建该活动。

    //优先存储您的主题ID

    saveThemeInPreferences(R.style.AppTheme_RED);
    //recreate this activity to see changes
    SettingActivity.this.recreate();
    
  4. 有关详细信息和示例代码...... 看看 Android multi theme implementation