Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

I have a fragment that implements RecyclerView.OnItemTouchListener. How to pass click and long press only motion events from RecyclerView to GestureDetectorCompat. That is, I mean that I only want to handle clicks and long clicks, the rest of the events should be handled by RecyclerView, as it usually happens. How can I customize this?

public class MyFragment extends Fragment implements RecyclerView.OnItemTouchListener, GestureDetector.OnGestureListener { protected RecyclerView recyclerView; protected RecyclerView.Adapter adapter; protected LinearLayoutManager layoutManager; private GestureDetectorCompat detector; public MyFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.myfrag, container, false); recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview); layoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(layoutManager); recyclerView.addOnItemTouchListener(this); adapter = new MyAdapter(myData)); recyclerView.setAdapter(adapter); return rootView; } @Override public boolean onDown(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) { return false; } @Override public void onTouchEvent(RecyclerView recyclerView, MotionEvent event) { } } 
0
java android gesture android-recyclerview
Oct 23 '14 at 8:23
source share
2 answers

You must initialize the GestureDetectorCompat method in onCreateView() :

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.myfrag, container, false); detector = new GestureDetectorCompat(getActivity(), new RecyclerViewOnGestureListener()); recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview); layoutManager = new LinearLayoutManager(getActivity()); recyclerView.setLayoutManager(layoutManager); recyclerView.addOnItemTouchListener(this); adapter = new MyAdapter(myData)); recyclerView.setAdapter(adapter); return rootView; } 

RecyclerViewOnGestureListener is your own inner class extending SimpleOnGestureListener (which provides an empty implementation of OnGestureListener methods)

 private class RecyclerViewOnGestureListener extends SimpleOnGestureListener { @Override public boolean onSingleTapConfirmed(MotionEvent e) { View view = recyclerView.findChildViewUnder(e.getX(), e.getY()); int position = recyclerView.getChildPosition(view); // handle single tap return super.onSingleTapConfirmed(e); } public void onLongPress(MotionEvent e) { View view = recyclerView.findChildViewUnder(e.getX(), e.getY()); int position = recyclerView.getChildPosition(view); // handle long press super.onLongPress(e); } } 

Now look at the line (from the onCreateView() method):

 recyclerView.addOnItemTouchListener(this); 

In our case, 'this' has an OnItemTouchListener containing two methods that we need to implement:

 @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { detector.onTouchEvent(e); return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } 

Here is an explanation of what these methods mean: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnItemTouchListener.html

This is all you need to handle single clicks and long click events from RecyclerView .

+20
Oct 23 '14 at 1:55
source share

I'm probably late, but for visual feedback, add this to your list_item layout.

 android:background="@drawable/tranparent_selector" android:clickable="true" android:focusable="true" android:focusableInTouchMode="true" 

In addition, onSingleTapUp can be used instead of onSingleTapConfirmed, as tapping is usually quick. Therefore, if you quickly click on other items, you will not get his work. For quick listening, I prefer onSingleTapUp

+2
Feb 20 '15 at 13:24
source share



All Articles