Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnLongItemClick in RecyclerView

Tags:

I am starting to use RecyclerView in Android. Things work fine until I implement touch listener for my adapter.

From this topic:

https://stackoverflow.com/a/26826692/2923403

I can implement the listener for childview correctly. However, I would like to implement both OnItemClick and OnItemLongClick, then problem appear. They are always fired at the same time. OnItemClick first and OnItemLongClick later, which renders my function useless.

Here is my code for the custom listener (based on the code above, thanks to Fouad):

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { private OnItemClickListener mListener;  public static interface OnItemClickListener {     public boolean onItemClick(View view, int position);      public void onItemLongClick(View view, int position); }  GestureDetector mGestureDetector;  public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {     mListener = listener;     mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {         @Override         public boolean onSingleTapUp(MotionEvent e) {             return true;         }          @Override         public void onLongPress(MotionEvent e) {             View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());              if (childView != null && mListener != null) {                 mListener.onItemLongClick(childView, recyclerView.getChildPosition(childView));             }         }      }); }  @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {      View childView = view.findChildViewUnder(e.getX(), e.getY());     if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {         mListener.onItemClick(childView, view.getChildPosition(childView));         return true;     }     return false; }  @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } 

And for the implementation:

mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(),   mRecyclerView, new RecyclerItemClickListener.OnItemClickListener() { @Override  public boolean onItemClick(View view, int position) { //This is fired 1st }  @Override  public void onItemLongClick(View view, int position) { //This comes later })); 

Do you have any solution for that?

like image 343
Souris Avatar asked Jan 14 '15 14:01

Souris


1 Answers

You can add listeners in your custom adapter implementation. It will be something like:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {      public interface OnItemClickListener {         public void onItemClicked(int position);     }      public interface OnItemLongClickListener {         public boolean onItemLongClicked(int position);     }      private Fragment mFragment;      public static class ViewHolder extends RecyclerView.ViewHolder {         public View v;          public ViewHolder(View v) {             super(v);             this.v = v;         }     }      public RecyclerViewAdapter(Fragment fragment) {         mFragment = fragment;     }      @Override     public void onBindViewHolder(ViewHolder holder, final int position) {         holder.v.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 mFragment.onItemClicked(position);             }         });         holder.v.setOnLongClickListener(new View.OnLongClickListener() {             @Override             public boolean onLongClick(View v) {                 mFragment.onItemLongClicked(position);                 return true;             }         });     }     . . . } 

Note interfaces definition at the beginning. This way you're passing onClick and onLongClick events to your fragment for handling. Pretty much convenient, you know

like image 117
Alexander Zhak Avatar answered Sep 21 '22 17:09

Alexander Zhak