Reputation: 11931
I am trying to add Ripple Effect to RecyclerView's item. I had a look online, but could not find what I need. I assume it has to be a custom effect. I have tried android:background attribute to the RecyclerView itself and set it to "?android:selectableItemBackground" but it did not work.:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:clickable="true"
android:background="?android:selectableItemBackground"
android:id="@+id/recyclerView"
android:layout_below="@+id/tool_bar"/>
This is the RecyclerView that I am trying to add the effect to:
Upvotes: 139
Views: 96132
Reputation: 1408
This has worked for me countlessly.
Add the Borderless Button Style to the root element of your layout.
There's no need for focusable
or clickable
attributes, the default styling encapsulates all that for you.
<androidx.constraintlayout.widget.ConstraintLayout
style="@android:style/Widget.Material.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content">
Upvotes: 5
Reputation: 10364
some_view.xml
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:src="@drawable/up_arrow"
android:theme="@style/SomeButtonTheme"/>
some_style.xml
<style name="SomeButtonTheme" >
<item name="colorControlHighlight">@color/someColor</item>
</style>
Other custom implementations may be found here.
Upvotes: 4
Reputation: 11931
I figured out. The only thing that I had to do is to add this attribute:
android:background="?android:attr/selectableItemBackground"
to the root element of the layout that my RecyclerView adapter inflates like that:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:background="?android:attr/selectableItemBackground"
tools:background="@drawable/bg_gradient">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:id="@+id/shoppingListItem"
android:hint="@string/enter_item_hint"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/shopping_list_item_checkbox_label"
android:id="@+id/shoppingListCheckBox"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:checked="false"/>
</RelativeLayout>
Result:
If you are still not able to see ripple effect, add these lines also to the root element of the layout.
android:clickable="true"
android:focusable="true"
Upvotes: 307
Reputation: 2603
add this lines in your adapter xml root view
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
Upvotes: 9
Reputation: 2229
I think there is one small detail that is missed.
If you still do not get the ripple effect after adding android:background="?android:attr/selectableItemBackground"
try adding these following lines in the root of the layout.
android:clickable="true"
android:focusable="true"
These will make sure that the view is clickable and will enable the ripple effect with the background attribute mentioned above
Upvotes: 33
Reputation: 511626
As already answered, the simplest solution is to just add one of the following as your RecyclerView
row's background:
android:background="?android:attr/selectableItemBackground"
android:background="?attr/selectableItemBackground"
However if you are experiencing problems with this method or if you want finer control over the colors, then you can do the following.
This answer is starting with this simple Android RecyclerView example. It will look like the following image.
Before API 21 (Android 5.0 Lollipop), clicking a RecyclerView
item just changed its background color (no ripple effect). That is what we are going to do, too. If you still have users with those devices, they are used to that behavior, so we aren't going to worry about them too much. (Of course, if you really want the ripple effect for them, too, you could use a custom library.)
Right click your res/drawable
folder and choose New > Drawable resource file. Call it custom_ripple
. Click OK and paste in the following code.
custom_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/colorAccent" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@android:color/transparent" />
</shape>
</item>
</selector>
I used colorAccent
as the highlight color for the pressed state because it was already available, but you can define whatever color you want.
Right click your res/drawable
folder and choose New > Drawable resource file. Call it custom_ripple
again. Don't click OK, yet this time, though. From the Available qualifiers list choose Version, then click the >> button and write 21
for the Platform API level. Now click OK and paste in the following code.
v21/custom_ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/colorAccent">
<item
android:id="@android:id/mask"
android:drawable="@android:color/white" />
</ripple>
Again, I used colorAccent
for the ripple color because it was available, but you can use whatever color you want. The mask confines the ripple effect to just the row layout. The mask color apparently doesn't matter so I just used an opaque white.
In your RecyclerView item's root layout, set the background to the custom ripple that we created.
android:background="@drawable/custom_ripple"
In the example project that we started with, it looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/custom_ripple"
android:padding="10dp">
<TextView
android:id="@+id/tvAnimalName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"/>
</LinearLayout>
That's it. You should be able to run your project now. Thanks to this answer and this YouTube video for help.
Upvotes: 94