RIpple effect on RecyclerView not working on light tap
Asked Answered
C

3

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?

Coverdale answered 16/5, 2017 at 10:4 Comment(1)
Use selectableItemBackgroundBorderless. I think Marshmallow changed the behavior of selectableItemBackground so it shows the ripple only for longer taps.Patronizing
G
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.

Galven answered 11/7, 2017 at 22:31 Comment(0)
D
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
      }
   })
);
Dishcloth answered 22/9, 2017 at 12:37 Comment(0)
S
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);
Superb answered 29/3, 2020 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.