如何为一个活动切换主题。

3

以下是需要翻译的内容:

这里是情况:

  1. 我有一个名为 DogActivityFavoritesActivity 的应用。其中,DogActivity 是一个 ListView。当你在列表中点击一个 Dog 后,它会带你进入 FavoritesActivity
  2. 我想要准备一些主题,它们不需要动态生成。它们可以已经以 XML 形式存在。
  3. 根据用户从列表中选择的狗,我想要将 FavoritesActivity 显示为我预先存在的某个主题。

我听说过 ContextWrapper,但我不确定如何应用它。你有什么想法吗?

细节:

这是通常的单一主题:

for 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 给所有人。 - Nouvel Travay
3个回答

2

您只需将狗类型作为 Intent 额外传递,然后使用 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中选择的狗的类型:

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 - Nouvel Travay
啊,TabLayout 使它有点复杂。首先,请查看我在这里的其他答案:https://dev59.com/plwY5IYBdhLWcg3wcXeE#32613364 我不确定你如何在运行时更改它.... - Daniel Nugent
这可能是我能得到的最好的答案。所以谢谢! - Nouvel Travay

1

在我的最新项目中,我已经很简单地完成了它,你只需要通过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, boolean)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接