Ripple effect on Android Lollipop CardView

AndroidAndroid LayoutAndroid 5.0-LollipopAndroid Cardview

Android Problem Overview


I'm trying to get a CardView to display the ripple effect when touched by setting the android:backgound attribute in the activity XML file as described here on the Android Developers page, but it isn't working. No animation at all, but the method in onClick is called. I've also tried creating a ripple.xml file as suggested here, but same result.

The CardView as it appears in the activity's XML file:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="155dp"
    android:layout_height="230dp"
    android:elevation="4dp"
    android:translationZ="5dp"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:onClick="showNotices"
    android:background="?android:attr/selectableItemBackground"
    android:id="@+id/notices_card"
    card_view:cardCornerRadius="2dp">

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

I'm relatively new to android development, so I might have made a few obvious mistakes.

Android Solutions


Solution 1 - Android

You should add following to CardView:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

Solution 2 - Android

I managed to get the ripple effect on the cardview by :

<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:clickable="true" 
    android:foreground="@drawable/custom_bg"/>

and for the custom_bg that you can see in above code, you have to define a xml file for both lollipop(in drawable-v21 package) and pre-lollipop(in drawable package) devices. for custom_bg in drawable-v21 package the code is:

<ripple 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:attr/colorControlHighlight">
<item
    android:id="@android:id/mask"
    android:drawable="@android:color/white"/>
</ripple>

for custom_bg in the drawable package, code is:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true">
    <shape>
        <solid android:color="@color/colorHighlight"></solid>
    </shape>
</item>
<item>
    <shape>
        <solid android:color="@color/navigation_drawer_background"></solid>
    </shape>
</item>
</selector>

so on pre-lollipop devices you will have a solid click effect and on lollipop devices you will have a ripple effect on the cardview.

Solution 3 - Android

The ripple effect was omitted in the appcompat support library which is what you're using. If you want to see the ripple use the Android L version and test it on an Android L device. Per the AppCompat v7 site:

"Why are there no ripples on pre-Lollipop? A lot of what allows RippleDrawable to run smoothly is Android 5.0’s new RenderThread. To optimize for performance on previous versions of Android, we've left RippleDrawable out for now."

Check out this link [here][1] for more info

[1]: http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html "here"

Solution 4 - Android

If the app minSdkVersion which you are working is level 9, you can use:

android:foreground="?selectableItemBackground"
android:clickable="true"

Instead, starting from level 11, you use:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

From documentation:

> clickable - Defines whether this view reacts to click events. Must be a boolean value, either "true" or "false". > > foreground - Defines the drawable to draw over the content. This can be used as an overlay. The foreground drawable participates in the padding of the content if the gravity is set to fill.

Solution 5 - Android

Use Material Cardview instead, it extends Cardview and provides multiple new features including default clickable effect :

<com.google.android.material.card.MaterialCardView>

...

</com.google.android.material.card.MaterialCardView>

Dependency (It can be used up to API 14 to support older device):

implementation 'com.google.android.material:material:1.0.0'

Solution 6 - Android

For me, adding the foreground to CardView didn't work (reason unknown :/)

Adding the same to it's child layout did the trick.

CODE:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:focusable="true"
    android:clickable="true"
    card_view:cardCornerRadius="@dimen/card_corner_radius"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:id="@+id/card_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:padding="@dimen/card_padding">

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

Solution 7 - Android

Add these two like of code work like a charm for any view like Button, Linear Layout, or CardView Just put these two lines and see the magic...

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

Solution 8 - Android

Add the following to your xml:

android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"

And add to your adapter (if it's your case)

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val attrs = intArrayOf(R.attr.selectableItemBackground)
            val typedArray = holder.itemView.context.obtainStyledAttributes(attrs)
            val selectableItemBackground = typedArray.getResourceId(0, 0)
            typedArray.recycle()

            holder.itemView.isClickable = true
            holder.itemView.isFocusable = true
            holder.itemView.foreground = holder.itemView.context.getDrawable(selectableItemBackground)
        }
    }

Solution 9 - Android

Ripple event for android Cardview control:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:layout_marginBottom="4dp"
    android:layout_marginTop="4dp" />

Solution 10 - Android

If there is a root layout like RelativeLayout or LinearLayout which contain all of the adapter item's component in CardView, you have to set background attribute in that root layout. like:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="122dp"
android:layout_marginBottom="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
card_view:cardCornerRadius="4dp">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/touch_bg"/>
</android.support.v7.widget.CardView>

Solution 11 - Android

For those searching for a solution to the issue of the ripple effect not working on a programmatically created CardView (or in my case custom view which extends CardView) being shown in a RecyclerView, the following worked for me. Basically declaring the XML attributes mentioned in the other answers declaratively in the XML layout file doesn't seem to work for a programmatically created CardView, or one created from a custom layout (even if root view is CardView or merge element is used), so they have to be set programmatically like so:

private class MadeUpCardViewHolder extends RecyclerView.ViewHolder {
    private MadeUpCardView cardView;

    public MadeUpCardViewHolder(View v){
        super(v);

        this.cardView = (MadeUpCardView)v;

        // Declaring in XML Layout doesn't seem to work in RecyclerViews
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int[] attrs = new int[]{R.attr.selectableItemBackground};
            TypedArray typedArray = context.obtainStyledAttributes(attrs);
            int selectableItemBackground = typedArray.getResourceId(0, 0);
            typedArray.recycle();

            this.cardView.setForeground(context.getDrawable(selectableItemBackground));
            this.cardView.setClickable(true);
        }
    }
}

Where MadeupCardView extends CardView Kudos to this answer for the TypedArray part.

Solution 12 - Android

I wasn't happy with AppCompat, so I wrote my own CardView and backported ripples. Here it's running on Galaxy S with Gingerbread, so it's definitely possible.

Demo of Ripple on Galaxy S

For more details check the source code.

Solution 13 - Android

  android:foreground="?android:attr/selectableItemBackgroundBorderless"
   android:clickable="true"
   android:focusable="true"

Only working api 21 and use this not use this list row card view

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAkraticCriticView Question on Stackoverflow
Solution 1 - AndroidJaden GuView Answer on Stackoverflow
Solution 2 - AndroidRahul AhujaView Answer on Stackoverflow
Solution 3 - AndroidDeveloper PaulView Answer on Stackoverflow
Solution 4 - AndroidFilipe BritoView Answer on Stackoverflow
Solution 5 - AndroidAnkit GuptaView Answer on Stackoverflow
Solution 6 - AndroidPrabsView Answer on Stackoverflow
Solution 7 - AndroidHitesh KushwahView Answer on Stackoverflow
Solution 8 - AndroidMateus MeloView Answer on Stackoverflow
Solution 9 - AndroidchavanNilView Answer on Stackoverflow
Solution 10 - AndroidRobert LeeView Answer on Stackoverflow
Solution 11 - AndroidBreenoView Answer on Stackoverflow
Solution 12 - AndroidZielonyView Answer on Stackoverflow
Solution 13 - AndroidTarun UmathView Answer on Stackoverflow