如何切换 activity 的主题
How to Switch theme for an activity
情况是这样的:
- 我有
DogActivity
和 FavoritesActivity
。 DogActivity
只是一个 ListView
。当您单击列表中的 Dog
时,它会将您带到 FavoritesActivity
.
- 我想准备一些主题。它们不需要动态生成。它们可能已经以 XML 形式存在。
- 根据用户从列表中选择的狗,我希望
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>
想我想做:
本质上,我只想即时更改 colorPrimary
、colorPrimaryDark
和 colorAccent
,并拥有使用它们的所有样式和主题以及 XML 布局改变。因此,如果我可以在启动 FavoritesActivity
之前更改这些颜色,那将解决我的问题。
我在最近的项目中很简单地完成了它,你只需要通过 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, 布尔值)
您可以只将狗类型作为 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);
//.....
}
您可以使用 this.recreate()
方法。
基于 答案。
情况是这样的:
- 我有
DogActivity
和FavoritesActivity
。DogActivity
只是一个ListView
。当您单击列表中的Dog
时,它会将您带到FavoritesActivity
. - 我想准备一些主题。它们不需要动态生成。它们可能已经以 XML 形式存在。
- 根据用户从列表中选择的狗,我希望
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>
想我想做:
本质上,我只想即时更改 colorPrimary
、colorPrimaryDark
和 colorAccent
,并拥有使用它们的所有样式和主题以及 XML 布局改变。因此,如果我可以在启动 FavoritesActivity
之前更改这些颜色,那将解决我的问题。
我在最近的项目中很简单地完成了它,你只需要通过 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, 布尔值)
您可以只将狗类型作为 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);
//.....
}
您可以使用 this.recreate()
方法。
基于