7

I want the items in a RecyclerView to have touch feedback or ripples when pressed, but they seem to not be working, and I think it's because of the checkbox.

The ripple is only shown when long pressing, but a simple press won't show it.

May someone help me to fix it? Thanks in advance.

PD: I was using a ListView, and the item layout parent was a LinearLayout. The ripples were working fine. After moving to RecyclerView, the items ripples don't work. I tried with the LinearLayout again, but still not working.

Here's the layout file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/requestCard"
    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:background="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/imgIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:adjustViewBounds="true"
        android:maxHeight="64dp"
        android:maxWidth="64dp"
        android:padding="@dimen/lists_padding"
        android:src="@drawable/ic_launcher"
        tools:ignore="ContentDescription"/>

    <TextView
        android:id="@+id/txtName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toEndOf="@+id/imgIcon"
        android:layout_toRightOf="@+id/imgIcon"
        android:ellipsize="end"
        android:maxLength="@integer/request_text_length"
        android:maxLines="1"
        android:padding="@dimen/lists_padding"
        android:textSize="@dimen/abc_text_size_large_material"
        tools:text="App Name"/>

    <CheckBox
        android:id="@+id/chkSelected"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="false"
        android:padding="@dimen/lists_padding"/>

</RelativeLayout>
Jahir Fiquitiva
  • 1,459
  • 3
  • 23
  • 47
  • Add android:descendantFocusability="blocksDescendants" in the root element of your item. – Gabriele Mariotti Dec 10 '15 at 07:57
  • @GabrieleMariotti already did. Still not working. Updated layout file. – Jahir Fiquitiva Dec 17 '15 at 04:18
  • I'm not quite sure, but this could happen because the views in the viewgroup cover your ripple effect. So it's there, but you can't see it.So I ended up in adding an extra simple view (with match_parent width and height) specifically for ripple. You may want to give it a try. – DmitryO. Dec 19 '15 at 10:54

4 Answers4

9

In your onClick method (assuming in your callback), make sure you do not call notifyDataSetChanged() after notifyItemChanged(position).

notifyDataSetChanged() will conflict with those default ripple effects.

new recyclerAdapter.ClickListener() {
    @Override
    public void onClick(int position) {

        ... awesome item onClick code ...

        notifyItemChanged(position);
        //notifyDataSetChanged(); <//--- Causes the no ripple bug
    }
};
Codeversed
  • 9,287
  • 3
  • 43
  • 42
1

You use android:background="?android:attr/selectableItemBackground" but you should use android:foreground="?android:attr/selectableItemBackground"

curioushikhov
  • 2,461
  • 2
  • 30
  • 44
  • I've just tried your layout in test project and all works fine - https://drive.google.com/file/d/0B5KouoPaI5qqQWFRenVpRkRlQ3M/view?usp=sharing – curioushikhov Dec 18 '15 at 11:49
  • @curioshikhov I have tried the same layout, still got nothing ... Is there somewhere I could contact you and get your help? I can't share the full source because is private, but if you're willing to help I may do it, thanks in advance. – Jahir Fiquitiva Dec 28 '15 at 16:24
1

I think you are looking for ripple effect.I can give you basic idea, Just create one xml file (ripple.xml) in drawable & write this code inside

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white"
        >

    </item>
</ripple>

& just write two line in your another xml file in which you have declared recyclerview elements.

android:background="@drawable/ripple"
android:clickable="true"

Like in my case i am having only TextView and in parent tag i am declaring these two lines

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ripple"
    android:clickable="true"
   >

<TextView
    android:id="@+id/textView_Username"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="30sp"
    android:textColor="@color/colorPrimary"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="10dp"
    />
</LinearLayout>

Finally the result:enter image description here

See this video

https://www.youtube.com/watch?v=qvVkDb7DqCk

Däñish Shärmà
  • 2,891
  • 2
  • 25
  • 43
0

I was using a custom ripple setting it on the background attribute of my parent layout

android:background="@drawable/bgr_collection_item"

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?colorControlHighlight">
    <!--  the ripple's color (1) -->

    <!--  no `id` so our <shape> will be drawn and not just used as mask -->
    <item>
        <shape>
            <corners android:radius="16dp" />
            <solid android:color="@color/white" />
        </shape>
    </item>

</ripple>

notifyItemChanged(position); was not disabling the ripple, but speeding it up.

Using recyclerView.setItemAnimator(null); allowed the original ripple animation to happen when calling notifyItemChanged(position);

Credits go to this answer: https://stackoverflow.com/a/43888196/11110509

DIRTY DAVE
  • 2,523
  • 2
  • 20
  • 83