【问题标题】:How to Switch theme for an activity如何为活动切换主题
【发布时间】:2016-09-06 19:38:37
【问题描述】:

所以情况如下:

  1. 我有DogActivityFavoritesActivityDogActivity 只是一个 ListView。当您单击列表中的Dog 时,它会将您带到FavoritesActivity
  2. 我想准备好一些主题。它们不需要动态生成。它们可能已经以 XML 形式存在。
  3. 根据用户从列表中选择的狗,我希望在我现有的主题之一中显示FavoritesActivity

我听说过ContextWrapper,但我不知道如何应用它。有什么想法可以做到这一点吗?

详情:

这是通常的单一主题:

适用于 v21/styles.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:colorControlHighlight">@color/colorAccentLight</item>
        <item name="android:colorControlNormal">@color/colorAccent</item>
        <item name="android:itemTextAppearance">@style/AppTheme.itemTextStyle</item>
        <item name="popupMenuStyle">@style/PopupMenu.MyAppTheme</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:colorControlHighlight">@color/colorAccentLight</item>
    </style>

    <style name="AppTheme.itemTextStyle" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@color/colorPrimary</item>
    </style>
</resources>

用于styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

我想做的事:

基本上我只是想即时更改colorPrimarycolorPrimaryDarkcolorAccent,并拥有使用它们来更改的所有样式和主题以及XML 布局。因此,如果我可以在启动 FavoritesActivity 之前更改这些颜色,那将解决我的问题。

【问题讨论】:

  • 回复的人,我没有缺席。我在这里。我正在实施你的建议。我在layout.xml 文件中直接使用 colorPrimary 或 colorAccent 时遇到了一些问题。他们并没有一起改变。目前只有原色在变化,我的意思是 colorPrimary 和 colorPrimaryDark。到目前为止,除非我可以直接更改这些颜色的值,否则我很不走运。同时,向所有人 +1。

标签: android android-layout android-theme android-styles


【解决方案1】:

您可以将狗类型作为 Intent extra 发送,然后使用 setTheme() 方法设置适当的主题。

对于这个例子,假设你只有两个主题:

<style name="AppThemeOne" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="AppThemeTwo" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimaryCustom</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDarkCustom</item>
    <item name="colorAccent">@color/colorAccentCustom</item>
</style>

然后,在 DogActivity 中,将 Intent Extra 设置为用户从 ListView 中选择的 Dog 类型:

Intent intent = new Intent(DogActivity.this, FavoritesActivity.class);
intent.putExtra("dog_type", "terrier");
startActivity(intent);

然后,在FavoritesActivity 中,加载正确的主题:

@Override
protected void onCreate(Bundle savedInstanceState) {

    String dogType = getIntent().getStringExtra("dog_type");
    if (dogType.equals("terrier")) {
        setTheme(R.style.AppThemeOne);
    } else {
        setTheme(R.style.AppThemeTwo);
    }
    super.onCreate(savedInstanceState);
    setContentView(R.layout.favorites_layout);
    //.....
 }

【讨论】:

  • 我正在使用你的实现。你已经看到了我的主题 v21。有没有办法在该主题中为android.support.design.widget.TabLayout 设置颜色?我的意思是tabIndicatorColortabSelectedTextColor
  • 啊,TabLayout 有点复杂。首先,请在此处查看我的其他答案:stackoverflow.com/a/32613364/4409409 我不确定您如何即时更改它....
  • 这可能是我能得到的最佳答案。所以谢谢!
【解决方案2】:

我在我的最新项目中非常简单地完成了它,您只需通过 Java 设置主题的值。像下面的代码:

public class FavoritesActivity extends AppCompatActivity { // it can be Activity too

@Override
public void onCreate(Bundle savedInstanceState) {
   if( ... check condition to change theme ) {
      // this will replace every value from FavoritesActivity theme by the
      // the values on `other_style` theme. 
      getTheme().applyStyle(R.style.other_style, true);
   }
   // call super AFTER applying the theme
   super.onCreate(savedInstanceState);

   .. carry on your normal stuff
}

这非常有用,因为您可以很容易地只替换几个值并将其余值保留为原始值,或者更改原始值的所有内容。这完全取决于您传递给applyTheme 方法的参数。

您不必使用 ContextThemeWrapper 进行模拟也很棒。价值观就在主题上,就是这样。

https://developer.android.com/reference/android/content/res/Resources.Theme.html#applyStyle(int,布尔值)

【讨论】:

    【解决方案3】:

    您可以为此使用this.recreate() 方法。

    基于https://stackoverflow.com/a/29722976/7547681 的回答。

    【讨论】:

      猜你喜欢
      • 2022-09-23
      • 1970-01-01
      • 2021-04-26
      • 2020-06-14
      • 2020-07-08
      • 2015-07-22
      • 1970-01-01
      • 2018-07-30
      • 2019-08-17
      相关资源
      最近更新 更多