Search code examples
androidandroid-5.0-lollipopandroid-cardview

Attach custom CardView style to theme


In my app, I have two themes (light and dark), and I want all of my CardViews to change their background color depending on which theme is selected.

What I don't want is:

<android.support.v7.widget.CardView
    style="@style/CardView.MyBlue"
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:layout_gravity="center_horizontal">

The above code is not dynamic. I need my two styles to automatically be applied depending on if a light or a dark theme is selected.


What I have right now doesn't work:

<style name="AppTheme.Light" parent="Theme.AppCompat.Light">
   ...
   <item name="cardViewStyle">@style/CardViewStyle.Light</item>
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat">
   ...
   <item name="cardViewStyle">@style/CardViewStyle.Dark</item>
</style>

<style name="CardViewStyle.Light" parent="CardView">
    <item name="cardBackgroundColor">@color/cardview_dark_background</item>
</style>

<style name="CardViewStyle.Dark" parent="CardView">
        <item name="cardBackgroundColor">@color/cardview_light_background</item>
</style>

I read somewhere that you can define a styleable.xml file in /res/values/ to key the word cardViewStyle, so I did that:

styleable.xml:

<resources>
    <declare-styleable name="AppTheme">
        <attr name="cardViewStyle" format="reference" />
    </declare-styleable>
</resources>

Update

Similar question here with no answer either.


Solution

  • In styles.xml

    <resources>
    
        <attr format="reference" name="cardStyle"/>
    
        <style name="Light" parent="Theme.AppCompat.NoActionBar">
            <item name="cardStyle">@style/CardView.Light</item>
            ...
        </style>
    
        <style name="Dark" parent="Theme.AppCompat.NoActionBar">
            <item name="cardStyle">@style/CardView.Dark</item>
            ...
        </style>
    </resources>
    

    Then in your other xml to use the new attribute, you would use it like this

    style="?attr/cardStyle"