【问题标题】:How to update my project creating a multi theme app如何更新我的项目以创建多主题应用程序
【发布时间】:2016-12-04 17:29:09
【问题描述】:

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

怎么可能呢?

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

编辑

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

【问题讨论】:

    标签: android themes


    【解决方案1】:

    这就是我为我的应用程序所做的。我相信我的方法会有所帮助。

    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.
            } 
        }
    

    如果 Back Navigation 导致 MainActivity,请务必在 onResume() 中重新创建您的 MainActivity


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

      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 中的工作方式:

    更新: Android 现在通过其 AppCompat DayNight Theme 正式支持夜间模式。 这是一个tutorial

    【讨论】:

      【解决方案2】:

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

      getApplication().setTheme(Theme.Holo)

      【讨论】:

      • 但是我怎么能简单地从 SettingsActivity 中的 CheckBox 更改应用程序的每个布局,全部采用单一样式?我的意思是,我拥有的每个视图都有自己的“个性化”
      • 您可以创建自己的样式并从清单文件中更改每个活动的样式,如果不知道如何创建自己的样式,我会告诉您如何。
      • 也许我要问的不清楚...我不想从清单中更改每个活动的单一样式。我想要一个 SettingsActivity,除了其他个性化设置之外,我可以在整个应用程序的多个主题(绿色、蓝色、黑色、白色、红色)之间切换,就像您在上面编辑中的图像中看到的那样。每个布局都有自己不同的视图,因此在我看来很难在样式中进行所有这些更改
      • 我明白了,你可以通过在你的设置活动中添加公共静态变量来做到这一点,这个变量你可以把你想要改变的所有可能的主题放在里面,当你改变主题时改变变量中的字符串,然后将我之前提到的上面的代码添加到 onCreate 方法中的每个活动,但要更改(Theme.Holo 到您的公共变量)。我希望这会有所帮助。
      • 这很有帮助,但我需要更详细的答案,因为作为 android 编程的新手,我从未使用过 PreferenceActvitiy
      【解决方案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

      附: R.style.ThemeBlack 是您在styles.xml 中的主题设置

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

      【讨论】:

        【解决方案4】:
        1. 首先,您需要以 xml 样式创建一些定义明确的主题。

          <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();
          

        更多细节和示例代码... 看看 Android multi theme implementation

        【讨论】:

          猜你喜欢
          • 2011-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-06
          • 1970-01-01
          • 1970-01-01
          • 2020-09-02
          • 1970-01-01
          相关资源
          最近更新 更多