Skip to content

Commit

Permalink
Improve long click handling of RecyclerViewDragDropManager
Browse files Browse the repository at this point in the history
  • Loading branch information
h6ah4i committed Jun 28, 2015
1 parent 52cf505 commit 5fe4b5b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
mRecyclerViewDragDropManager.setDraggingItemShadowDrawable(
(NinePatchDrawable) getResources().getDrawable(R.drawable.material_shadow_z3));
mRecyclerViewDragDropManager.setInitiateOnLongPress(true); // Start dragging after long press
// Start dragging after long press
mRecyclerViewDragDropManager.setInitiateOnLongPress(true);
mRecyclerViewDragDropManager.setInitiateOnMove(false);

//adapter
final MyDraggableItemAdapter myItemAdapter = new MyDraggableItemAdapter(getDataProvider());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
import android.graphics.Rect;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
Expand Down Expand Up @@ -100,7 +101,6 @@ public class RecyclerViewDragDropManager {

private RecyclerView.OnItemTouchListener mInternalUseOnItemTouchListener;
private RecyclerView.OnScrollListener mInternalUseOnScrollListener;
private GestureDetector mGestureDetector;

private EdgeEffectDecorator mEdgeEffectDecorator;
private NinePatchDrawable mShadowDrawable;
Expand Down Expand Up @@ -138,6 +138,7 @@ public class RecyclerViewDragDropManager {
private int mGrabbedItemHeight;
private int mOrigOverScrollMode;
private ItemDraggableRange mDraggableRange;
private InternalHandler mHandler;

/**
* Constructor.
Expand All @@ -156,6 +157,7 @@ public void onTouchEvent(RecyclerView rv, MotionEvent e) {

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
RecyclerViewDragDropManager.this.onRequestDisallowInterceptTouchEvent(disallowIntercept);
}
};

Expand Down Expand Up @@ -263,24 +265,7 @@ public void attachRecyclerView(RecyclerView rv, RecyclerViewOnScrollEventDistrib
mDisplayDensity = mRecyclerView.getResources().getDisplayMetrics().density;
mTouchSlop = ViewConfiguration.get(mRecyclerView.getContext()).getScaledTouchSlop();
mScrollTouchSlop = (int) (mTouchSlop * SCROLL_TOUCH_SLOP_MULTIPLY + 0.5f);

mGestureDetector = new GestureDetector(mRecyclerView.getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
handleOnLongPress(e);
}

@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}

@Override
public boolean onDown(MotionEvent e) {
return true;
}
});
mGestureDetector.setIsLongpressEnabled(true);
mHandler = new InternalHandler(this);

if (supportsEdgeEffect()) {
// edge effect is available on ICS or later
Expand All @@ -297,6 +282,11 @@ public boolean onDown(MotionEvent e) {
public void release() {
cancelDrag();

if (mHandler != null) {
mHandler.release();
mHandler = null;
}

if (mEdgeEffectDecorator != null) {
mEdgeEffectDecorator.finish();
mEdgeEffectDecorator = null;
Expand Down Expand Up @@ -401,8 +391,6 @@ public Interpolator setSwapTargetTranslationInterpolator() {
Log.v(TAG, "onInterceptTouchEvent() action = " + action);
}

mGestureDetector.onTouchEvent(e);

switch (action) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
Expand Down Expand Up @@ -442,8 +430,6 @@ public Interpolator setSwapTargetTranslationInterpolator() {
return;
}

mGestureDetector.onTouchEvent(e);

switch (action) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
Expand All @@ -457,6 +443,13 @@ public Interpolator setSwapTargetTranslationInterpolator() {
}
}

/*package */ void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
if (disallowIntercept) {
cancelDrag(true);
}
}


/*package*/ void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (LOCAL_LOGV) {
Log.v(TAG, "onScrolled(dx = " + dx + ", dy = " + dy + ")");
Expand Down Expand Up @@ -484,6 +477,10 @@ private boolean handleActionDown(RecyclerView rv, MotionEvent e) {
mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);
mInitialTouchItemId = holder.getItemId();

if (mInitiateOnLongPress) {
mHandler.startLongPressDetection(e);
}

return true;
}

Expand Down Expand Up @@ -649,6 +646,8 @@ private void finishDragging(boolean result) {
private boolean handleActionUpOrCancel(RecyclerView rv, MotionEvent e) {
final boolean result = (MotionEventCompat.getActionMasked(e) == MotionEvent.ACTION_UP);

mHandler.cancelLongPressDetection();

mInitialTouchY = 0;
mLastTouchY = 0;
mDragStartTouchY = 0;
Expand Down Expand Up @@ -1248,4 +1247,44 @@ public void run() {
}
}
}

private static class InternalHandler extends Handler {
private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();// + ViewConfiguration.getTapTimeout();
private static final int MSG_LONGPRESS = 1;

private RecyclerViewDragDropManager mHolder;
private MotionEvent mDownMotionEvent;

public InternalHandler(RecyclerViewDragDropManager holder) {
mHolder = holder;
}

public void release() {
removeCallbacks(null);
mHolder = null;
}

@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_LONGPRESS:
mHolder.handleOnLongPress(mDownMotionEvent);
break;
}
}

public void startLongPressDetection(MotionEvent e) {
cancelLongPressDetection();
mDownMotionEvent = MotionEvent.obtain(e);
sendEmptyMessageAtTime(MSG_LONGPRESS, e.getDownTime() + LONGPRESS_TIMEOUT);
}

public void cancelLongPressDetection() {
removeMessages(MSG_LONGPRESS);
if (mDownMotionEvent != null) {
mDownMotionEvent.recycle();
mDownMotionEvent = null;
}
}
}
}

0 comments on commit 5fe4b5b

Please sign in to comment.