Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

I have a Fragment that implemets RecyclerView.OnItemTouchListener. How do I pass click and long-click motion events only from the RecyclerView to the GestureDetectorCompat. That is I mean I only want to handle clicks and long-clicks, rest of the events should be handled by the RecyclerView as it would happen normally. How can I set this up?

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) {      } } 

回答1:

You have to initialize GestureDetectorCompat in onCreateView() method:

@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 (that provides 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 line (from onCreateView() method):

recyclerView.addOnItemTouchListener(this); 

In our case 'this' is OnItemTouchListener containing two methods 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 what these methods mean: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnItemTouchListener.html

It's all you need to handle single tap and long press events from RecyclerView.



回答2:

I might be 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" 

Also, onSingleTapUp can be used instead of onSingleTapConfirmed as tapping is usually fast. So if you tap fast to other items you wont get it working. For fast tapping I prefer onSingleTapUp



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!