While working with the recycler view , we often feel the need to implement a listener on the whole recycler view so that if any one item is selected we may trigger the action as per our need.
One way is to perform the same action on click of every element of the itemView in Recycler view’s onBindViewHolder function. But then that redundant, repetitive and also not at all good approach.
Another is to add the addOnItemTouchListener to your recycler view.
But problem with this is that you need to override the three methods viz :
- onInterceptTouchEvent
- onTouchEvent
- onRequestDisallowInterceptTouchEvent
and implementing this is not very easy, as two of these take motionevents as input and you need to know how to handle this or you can convert these to something that most of the listeners have(like onClick) and use them as per your need .
So lets begin the coding :
- Make a class that extends RecyclerView.OnItemTouchListener
- Make a interface in this class.
- Override the methods as shown in the code snippet.
- Use an instance of this class while adding addOnItemTouchListener to your recycler view.
CODE : for the class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
public class MyTouchListener implements RecyclerView.OnItemTouchListener { /*Change these as per your need*/ private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_THRESHOLD_VELOCITY = 200; private static final int SWIPE_MAX_OFF_PATH = 250; private OnTouchActionListener mOnTouchActionListener; private GestureDetectorCompat mGestureDetector; public static interface OnTouchActionListener { public void onLeftSwipe(View view, int position); public void onRightSwipe(View view, int position); public void onClick(View view, int position); } public MyTouchListener(Context context, final RecyclerView recyclerView, OnTouchActionListener onTouchActionListener){ mOnTouchActionListener = onTouchActionListener; mGestureDetector = new GestureDetectorCompat(context,new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onSingleTapConfirmed(MotionEvent e) { // Find the item view that was swiped based on the coordinates View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); int childPosition = recyclerView.getChildPosition(child); mOnTouchActionListener.onClick(child, childPosition); return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { try { if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) { return false; } // Find the item view that was swiped based on the coordinates View child = recyclerView.findChildViewUnder(e1.getX(), e1.getY()); int childPosition = recyclerView.getChildPosition(child); // right to left swipe if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { if (mOnTouchActionListener != null && child != null) { mOnTouchActionListener.onLeftSwipe(child, childPosition); } } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { if (mOnTouchActionListener != null && child != null) { mOnTouchActionListener.onRightSwipe(child, childPosition); } } } catch (Exception e) { // nothing } return false; } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { mGestureDetector.onTouchEvent(e); return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { // do nothing } } |
Now with this being done , all you need to do to your recycler view is to set an instance of this class.
take a look at how to do the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
myRecyclerView.addOnItemTouchListener(new MyTouchListener(mContext, myRecyclerView, new MyTouchListener.OnTouchActionListener() { @Override public void onLeftSwipe(View view, int position) { //code as per your need } @Override public void onRightSwipe(View view, int position) { //code as per your need } @Override public void onClick(View view, int position) { //code as per your need } })); |