Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Switch theme for an activity

So here is the situation:

  1. I have DogActivity and FavoritesActivity. DogActivity is just a ListView. When you click on a Dog in the list, it takes you to FavoritesActivity.
  2. I want to have a number of themes ready to go. They don’t need to be dynamically generated. They can already exist in XML form.
  3. Depending on which dog the user selects from the list, I want to have the FavoritesActivity shown in one of my pre-existing themes.

I hear talks about ContextWrapper, but I am not sure how to apply it. Any thoughts on how I may accomplish this?

Details:

Here is the usual single theme:

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>

for 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>

Want I want to do:

Essentially I just want to change the colorPrimary, colorPrimaryDark and colorAccent on the fly and have all the styles and themes and XML layouts that use them to change. So if I can change those colors before I launch FavoritesActivity then that would solve my problems.

like image 338
Nouvel Travay Avatar asked Oct 27 '25 10:10

Nouvel Travay


1 Answers

You can just send the dog type as an Intent extra, and then use the setTheme() method to set the appropriate Theme.

For this example, suppose you just have two Themes:

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

Then, in DogActivity, set an Intent Extra to the Dog type the user selected from the ListView:

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

Then, in FavoritesActivity, load the correct Theme:

@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);
    //.....
 }
like image 127
Daniel Nugent Avatar answered Oct 28 '25 23:10

Daniel Nugent