5

I have tried to implement the ripple effect on my RecyclerView. Here's my layout for it :

<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"
        android:layout_marginTop="7dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="5dp"
        android:clickable="true"
        card_view:cardElevation="5dp"
        android:focusable="true"
        android:foreground="?android:attr/selectableItemBackground">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="16dp">

                <TextView
                    //some properties />

                <TextView
                    //some properties />

                <TextView
                    //some properties />
            </LinearLayout>

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

In order to implement the onclick listener I basically followed this tutorial here: http://sapandiwakar.in/recycler-view-item-click-handler/

The problem is that the ripple effect,generated thanks to the lines :

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

is not working on light (it's to say quick) presses. When I just quickly tap the screen, the click listener is triggered. It means that the touch event have been detected, however there is no ripple effect showing. If I want to see the ripple effect, I have to maintain for a bit longer the pressure on the screen before releasing.

Is there a way to correct this behaviour and show a ripple effect even for quick presses?

Robin Dupont
  • 339
  • 1
  • 2
  • 12
  • Use `selectableItemBackgroundBorderless`. I think Marshmallow changed the behavior of `selectableItemBackground` so it shows the ripple only for longer taps. – Gergely Kőrössy Jul 11 '17 at 22:51

3 Answers3

7

I faced a similar problem. I had an ItemClickListener on the RecyclerView, and in that listener I was pushing a new fragment. By trial and error I noticed that removing or emptying the item click listener would get the highlight to show every time, even on light taps.

The fix was to change my onItemClick method:

@Override
public void onItemClick(final RecyclerView parent, final View view, final int position, final long id)
{
    ViewCompat.postOnAnimationDelayed(parent, new Runnable()
    {
        @Override
        public void run()
        {
            // Your click code goes here
        }
    }, 50);
}

This postpones your click action until 50ms after the next animation step and gives the animation enough time to load and run before your click action is performed.

Theo
  • 5,963
  • 3
  • 38
  • 56
2

This happens because you have used addOnItemTouchListener for item click listener. Just create an interface in RecyclerAdapter

In adapter create an interface

public interface OnItemClickListener {
    void onItemClick(Item item);
}

private final List<ContentItem> items;
private final OnItemClickListener listener;

public Adapter(List<ContentItem> items, OnItemClickListener listener) 
{
   this.items = items;
   this.listener = listener;
}

@Override 
public void onBindViewHolder(ViewHolder holder, int position) {
   holder.bind(items.get(position), listener);
}


//In your Activity
recycler.setAdapter(new Adapter(items, new 
Adapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
    Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));

instead of below code and it will work like a charm.

recyclerView.addOnItemTouchListener( 
    new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
      @Override public void onItemClick(View view, int position) {
        // TODO Handle item click
      }
   })
);
gadgetroid
  • 83
  • 4
0

Asked long ago but thought it might help someone, I faced the similar issue and used postDelayed method .

   ( new Handler()).postDelayed(new Runnable() {
        @Override
        public void run() {
           //your code 
        }
    }, 100);
NITIN DUDA
  • 192
  • 1
  • 14