Override Android-L CardView state_pressed for Older versions of Android

Smiler picture Smiler · Jul 1, 2014 · Viewed 14.3k times · Source

In the latest Android SDK we now have the new CardView, I have replaced my old CustomCardView with the new version, but when running with this on older versions of Android I see that the state_pressed & state_focused are ugly squares which show up above the CardView...

does anyone know how I could emulate the following in the new CardView but only when using older versions of Android?

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:enterFadeDuration="150"
    android:exitFadeDuration="150" >

    <item android:state_pressed="true"
          android:drawable="@drawable/card_on_press"/>
    <item android:state_focused="true" android:state_enabled="true"
          android:drawable="@drawable/card_on_focus"/>
    <item android:state_enabled="true"
          android:drawable="@drawable/card_default"/>
    <item android:state_enabled="false"
          android:drawable="@drawable/card_on_press"/>

</selector>

And for those of you interested here is the CardView that I am using now:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/CardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="10dp"
    android:foreground="?android:attr/selectableItemBackground"
    android:onClick="RunSomeMethod"
    card_view:cardCornerRadius="4dp"
    android:focusable="true"
    android:elevation="2dp">

    <LinearLayout
        android:id="@+id/LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:focusable="false"
        android:visibility="visible">

    </LinearLayout>
</android.support.v7.widget.CardView>

Answer

Smiler picture Smiler · Jul 6, 2014

Fixed with the following code:

values-v21\styles.xml:

<style name="CardViewStyle" parent="CardView.Light">
    <item name="android:foreground">?android:attr/selectableItemBackground</item>
</style>

values\styles.xml:

<style name="CardViewStyle" parent="android:Widget.TextView">
    <item name="android:foreground">@drawable/card</item>
</style>

A card from layout\main_layout.xml:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/Card_View"
    style="@style/CardViewStyle"
    android:layout_width="480dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_marginTop="10dp"
    card_view:cardCornerRadius="4dp"
    android:elevation="2dp">

This will allow you to offer the animations in v21+ but also offer alternative animations in pre-v21 rather than the big blue/grey square.

Here is the card.xml I'm using as a drawable for those of you interested:

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:enterFadeDuration="150"
    android:exitFadeDuration="150" >

    <item android:state_pressed="true"
          android:drawable="@drawable/card_on_press"/>
    <item android:state_focused="true" android:state_enabled="true"
          android:drawable="@drawable/card_on_focus"/>
    <item android:state_enabled="true"
          android:drawable="@drawable/card_default"/>
    <item android:state_enabled="false"
          android:drawable="@drawable/card_on_press"/>
</selector>

Note: Drawable default will be fine as a transparent item as CardView provides a default background for all android versions.