Created
January 22, 2017 20:51
-
-
Save NikolaDespotoski/b828f77e4b58c6d89583a49083abea24 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DragSelectionItemTouchListener extends LongPressItemTouchListener implements RecyclerView.OnItemTouchListener { | |
private RecyclerView.ViewHolder mPreviousViewHolder; | |
private Rect mHitRect = new Rect(); | |
private List<RecyclerView.ViewHolder> mRangeSelection = new ArrayList<>(); | |
public DragSelectionItemTouchListener(Context context, OnItemInteractionListener listener) { | |
super(context, listener); | |
} | |
@Override | |
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { | |
if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_POINTER_UP) { | |
cancelPreviousSelection(); | |
return false; | |
} else { | |
onLongPressedEvent(rv, e); | |
} | |
return mViewHolderLongPressed != null; | |
} | |
private void cancelPreviousSelection() { | |
mViewHolderLongPressed = null; | |
mViewHolderInFocus = null; | |
mPreviousViewHolder = null; | |
mRangeSelection.clear(); | |
} | |
private boolean onActionMove(RecyclerView rv, MotionEvent e) { | |
if (isMotionEventInCurrentViewHolder(e) || mViewHolderLongPressed == null) { | |
return false; | |
} | |
if (mViewHolderLongPressed != null && mPreviousViewHolder == null) { | |
mPreviousViewHolder = mViewHolderLongPressed; | |
} | |
View childViewUnder = rv.findChildViewUnder(e.getX(), e.getY()); | |
if (childViewUnder == null) return false; | |
RecyclerView.ViewHolder viewHolder = rv.getChildViewHolder(childViewUnder); | |
if (mPreviousViewHolder == null && viewHolder != null && mViewHolderLongPressed != null && viewHolder.getAdapterPosition() != mViewHolderLongPressed.getAdapterPosition()) { | |
dispatchOnViewHolderHovered(rv, viewHolder); | |
return true; | |
} else if (mPreviousViewHolder != null && viewHolder != null && viewHolder.getAdapterPosition() != mPreviousViewHolder.getAdapterPosition()) { | |
dispatchOnViewHolderHovered(rv, viewHolder); | |
return true; | |
} | |
return false; | |
} | |
private boolean isMotionEventInCurrentViewHolder(MotionEvent e) { | |
if (mPreviousViewHolder != null) { | |
mPreviousViewHolder.itemView.getHitRect(mHitRect); | |
return mHitRect.contains((int) e.getX(), (int) e.getY()); | |
} | |
return false; | |
} | |
private void dispatchOnViewHolderHovered(RecyclerView rv, RecyclerView.ViewHolder viewHolder) { | |
if (!checkForSpanSelection(rv, viewHolder)) { | |
if (mListener != null) { | |
mListener.onViewHolderHovered(rv, viewHolder); | |
} | |
} | |
mPreviousViewHolder = viewHolder; | |
} | |
private boolean checkForSpanSelection(RecyclerView rv, RecyclerView.ViewHolder viewHolder) { | |
if (rv.getLayoutManager() instanceof GridLayoutManager) { | |
GridLayoutManager.LayoutParams endSelectionParams = (GridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams(); | |
GridLayoutManager.LayoutParams startSelectionParams = (GridLayoutManager.LayoutParams) mPreviousViewHolder.itemView.getLayoutParams(); | |
if (endSelectionParams.getSpanIndex() != startSelectionParams.getSpanIndex()) { | |
dispatchRangeSelection(rv, viewHolder); | |
return true; | |
} | |
} | |
return false; | |
} | |
private void dispatchRangeSelection(RecyclerView rv, RecyclerView.ViewHolder viewHolder) { | |
if (mListener != null) { | |
mRangeSelection.clear(); | |
int start = Math.min(mPreviousViewHolder.getAdapterPosition() + 1, viewHolder.getAdapterPosition()); | |
int end = Math.max(mPreviousViewHolder.getAdapterPosition() + 1, viewHolder.getAdapterPosition()); | |
for (int i = start; i <= end; i++) { | |
mRangeSelection.add(rv.findViewHolderForAdapterPosition(i)); | |
} | |
mListener.onMultipleViewHoldersSelected(rv, mRangeSelection); | |
} | |
} | |
@Override | |
public void onTouchEvent(RecyclerView rv, MotionEvent e) { | |
if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_POINTER_UP) { | |
cancelPreviousSelection(); | |
} else if (mViewHolderLongPressed != null) { | |
onActionMove(rv, e); | |
} | |
} | |
@Override | |
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class LongPressItemTouchListener extends RecyclerView.SimpleOnItemTouchListener { | |
private final GestureDetector mGestureDetector; | |
protected final OnItemInteractionListener mListener; | |
protected RecyclerView.ViewHolder mViewHolderLongPressed; | |
public RecyclerView.ViewHolder mViewHolderInFocus; | |
public LongPressItemTouchListener(Context context, OnItemInteractionListener listener) { | |
mGestureDetector = new GestureDetector(context, new LongPressGestureListener()); | |
mGestureDetector.setIsLongpressEnabled(true); | |
mListener = listener; | |
} | |
public boolean onLongPressedEvent(RecyclerView rv, MotionEvent e) { | |
if (mViewHolderLongPressed != null) { | |
return false; | |
// long pressed happened, my job here is done. | |
} | |
View childViewUnder = rv.findChildViewUnder(e.getX(), e.getY()); | |
if (childViewUnder != null) { | |
mViewHolderInFocus = rv.findContainingViewHolder(childViewUnder); | |
if (mGestureDetector.onTouchEvent(e) && mListener != null) { | |
mListener.onItemClicked(rv, mViewHolderInFocus, rv.getChildAdapterPosition(childViewUnder)); | |
} | |
return mViewHolderLongPressed != null; | |
} | |
return false; | |
} | |
class LongPressGestureListener extends SimpleOnGestureListener { | |
@Override | |
public boolean onSingleTapUp(MotionEvent e) { | |
return true; | |
} | |
@Override | |
public boolean onSingleTapConfirmed(MotionEvent e) { | |
return true; | |
} | |
@Override | |
public void onLongPress(MotionEvent e) { | |
if (mViewHolderInFocus != null && mListener != null) { | |
RecyclerView recyclerView = (RecyclerView) mViewHolderInFocus.itemView.getParent(); | |
mListener.onLongItemClicked(recyclerView, mViewHolderInFocus, mViewHolderInFocus.getAdapterPosition()); | |
mViewHolderLongPressed = mViewHolderInFocus; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment