List of usage examples for android.support.v4.view MotionEventCompat getY
public static float getY(MotionEvent event, int pointerIndex)
From source file:com.icloud.listenbook.base.view.DraggableGridViewPager.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) { // Don't handle edge touches immediately -- they may actually belong // to one of our // descendants. return false; }/*from w w w . ja v a 2 s. c o m*/ if (mPageCount <= 0) { // Nothing to present or scroll; nothing to touch. return false; } // if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); final int action = ev.getAction(); boolean needsInvalidate = false; switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { // ? mScroller.abortAnimation(); // Remember where the motion event started // ?? mLastMotionX = mInitialMotionX = ev.getX(); mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); DEBUG_LOG("Down at " + mLastMotionX + "," + mLastMotionY + " mIsBeingDragged=" + mIsBeingDragged + " mIsUnableToDrag=" + mIsUnableToDrag); // ? if (!mIsBeingDragged && mScrollState == SCROLL_STATE_IDLE) { mLastPosition = getPositionByXY((int) mLastMotionX, (int) mLastMotionY); } else { mLastPosition = -1; } // if (mLastPosition >= 0) { mLastDownTime = System.currentTimeMillis(); } else { mLastDownTime = Long.MAX_VALUE; } DEBUG_LOG("Down at mLastPosition=" + mLastPosition); mLastDragged = -1; break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); // ? if (mLastDragged >= 0) { // change draw location of dragged visual // ? ? final View v = getChildAt(mLastDragged); final int l = getScrollX() + (int) x - v.getWidth() / 2; final int t = getScrollY() + (int) y - v.getHeight() / 2; v.layout(l, t, l + v.getWidth(), t + v.getHeight()); // check for new target hover // if (mScrollState == SCROLL_STATE_IDLE) { final int target = getTargetByXY((int) x, (int) y); // ?? ?? if (target != -1 && mLastTarget != target) { animateGap(target); mLastTarget = target; DEBUG_LOG("Moved to mLastTarget=" + mLastTarget); } // edge holding /** * ? * */ final int edge = getEdgeByXY((int) x, (int) y); if (mLastEdge == -1) { if (edge != mLastEdge) { mLastEdge = edge; mLastEdgeTime = System.currentTimeMillis(); } } else { // ?? 1.2 ? if (edge != mLastEdge) { mLastEdge = -1; } else { if ((System.currentTimeMillis() - mLastEdgeTime) >= EDGE_HOLD_DURATION) { // ??? performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); triggerSwipe(edge); mLastEdge = -1; } } } } } // ? else if (!mIsBeingDragged) { final float xDiff = Math.abs(x - mLastMotionX); final float yDiff = Math.abs(y - mLastMotionY); DEBUG_LOG("Moved to " + x + "," + y + " diff=" + xDiff + "," + yDiff); // ?? ??? if (xDiff > mTouchSlop && xDiff > yDiff) { DEBUG_LOG("Starting drag!"); mIsBeingDragged = true; requestParentDisallowInterceptTouchEvent(true); mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop : mInitialMotionX - mTouchSlop; mLastMotionY = y; setScrollState(SCROLL_STATE_DRAGGING); setScrollingCacheEnabled(true); } } // Not else! Note that mIsBeingDragged can be set above. if (mIsBeingDragged) { // Scroll to follow the motion event // ? needsInvalidate |= performDrag(x); } // ??? ? else if (mLastPosition >= 0) { final int currentPosition = getPositionByXY((int) x, (int) y); DEBUG_LOG("Moved to currentPosition=" + currentPosition); // ? if (currentPosition == mLastPosition) { // 1S? if ((System.currentTimeMillis() - mLastDownTime) >= LONG_CLICK_DURATION) { if (onItemLongClick(currentPosition)) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); mLastDragged = mLastPosition; requestParentDisallowInterceptTouchEvent(true); mLastTarget = -1; animateDragged(); mLastPosition = -1; } mLastDownTime = Long.MAX_VALUE; } } else { mLastPosition = -1; } } break; } case MotionEvent.ACTION_UP: { DEBUG_LOG("Touch up!!!"); final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); // ? if (mLastDragged >= 0) { rearrange(); } else if // ?? (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); final int width = getWidth(); final int scrollX = getScrollX(); final int currentPage = scrollX / width; final int offsetPixels = scrollX - currentPage * width; final float pageOffset = (float) offsetPixels / (float) width; final int totalDelta = (int) (x - mInitialMotionX); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); mActivePointerId = INVALID_POINTER; endDrag(); } else if (mLastPosition >= 0) { final int currentPosition = getPositionByXY((int) x, (int) y); DEBUG_LOG("Touch up!!! currentPosition=" + currentPosition); if (currentPosition == mLastPosition) { onItemClick(currentPosition); } } break; } case MotionEvent.ACTION_CANCEL: DEBUG_LOG("Touch cancel!!!"); // ? if (mLastDragged >= 0) { rearrange(); } else // ??? if (mIsBeingDragged) { scrollToItem(mCurItem, true, 0, false); mActivePointerId = INVALID_POINTER; endDrag(); } break; case MotionEventCompat.ACTION_POINTER_DOWN: { // ??? final int index = MotionEventCompat.getActionIndex(ev); final float x = MotionEventCompat.getX(ev, index); mLastMotionX = x; mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } case MotionEventCompat.ACTION_POINTER_UP: // ? onSecondaryPointerUp(ev); mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); break; } if (needsInvalidate) { ViewCompat.postInvalidateOnAnimation(this); } return true; }
From source file:co.codecrunch.musicplayerlite.slidinguppanelhelper.ViewDragHelper.java
private void saveLastMotion(MotionEvent ev) { final int pointerCount = MotionEventCompat.getPointerCount(ev); for (int i = 0; i < pointerCount; i++) { final int pointerId = MotionEventCompat.getPointerId(ev, i); final float x = MotionEventCompat.getX(ev, i); final float y = MotionEventCompat.getY(ev, i); if (mLastMotionX != null && mLastMotionY != null) { mLastMotionX[pointerId] = x; mLastMotionY[pointerId] = y; }/*from w w w .j a v a 2s. c om*/ } }
From source file:com.juick.android.MessagesFragment.java
public Boolean maybeInterceptTouchEventFromActivity(MotionEvent event) { if (rightScrollBound == 0) { Log.w("JAGP", "rightScrollBound == 0"); return null; }/*from w w w. j a v a2 s .c o m*/ if (getActivity() == null || true) return null; int action = event.getAction(); int actionMasked = event.getActionMasked(); if (fragInParent == null) fragInParent = getActivity().findViewById(R.id.messagesfragment); if (action == MotionEvent.ACTION_DOWN || actionMasked == MotionEvent.ACTION_POINTER_DOWN) { if (mScrollState == SCROLL_STATE_IDLE && fragInParent.getAnimation() == null) { if (!canStartScroll(event)) { mIsUnableToDrag = true; return null; } if (event.getPointerCount() == 1) { Log.w("JAGP", "action_down 1"); navigationOpenMode = fragInParent.getLeft() > 0; mLastMotionX = mInitialMotionX = event.getX(); mLastMotionY = event.getY(); currentScrollX = 0; mActivePointerId = MotionEventCompat.getPointerId(event, 0); mIsBeingDragged = false; mIsUnableToDrag = false; } else { Log.w("JAGP", "action_down 2"); if (mIsBeingDragged) { if (!navigationOpenMode) { Log.w("JAGP", "action_down 3"); setScrollState(SCROLL_STATE_IDLE); scrollToX(0, 500); } } mIsUnableToDrag = true; } } else { Log.w("JAGP", "!(mScrollState == SCROLL_STATE_IDLE && fragInParent.getAnimation() == null)"); } } if (action == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_POINTER_UP) { if (mIsUnableToDrag) return null; if (mIsBeingDragged) { final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { // If we don't have a valid id, the touch down wasn't on content. return null; } int pointerIndex = MotionEventCompat.findPointerIndex(event, activePointerId); if (pointerIndex == event.getActionIndex()) { if (!navigationOpenMode) { // commenting needed. if (lastToXDelta != null) { if (Math.abs(lastToXDelta) < rightScrollBound / 2) { Log.w("JAGP", "action_up 1"); setScrollState(SCROLL_STATE_SETTLING); scrollToX(0, 500); } else { Log.w("JAGP", "action_up 2"); setScrollState(SCROLL_STATE_SETTLING); scrollToX((int) -rightScrollBound, 200); handler.postDelayed(new Runnable() { @Override public void run() { Log.w("JAGP", "action_up 3"); ((MainActivity) getActivity()).openNavigationMenu(false); lastToXDelta = 0; fragInParent.clearAnimation(); } }, 200); } } } else { Log.w("JAGP", "action_up 4"); mIsBeingDragged = false; setScrollState(SCROLL_STATE_SETTLING); scrollToX((int) rightScrollBound, 200); mActivePointerId = INVALID_POINTER; handler.postDelayed(new Runnable() { @Override public void run() { Log.w("JAGP", "action_up 5"); ((MainActivity) getActivity()).closeNavigationMenu(false, true); lastToXDelta = 0; fragInParent.clearAnimation(); } }, 200); } return null; } } } if (action == MotionEvent.ACTION_MOVE) { if (mIsUnableToDrag) return null; if (mScrollState == SCROLL_STATE_SETTLING) return null; /* * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check * whether the user has moved far enough from his original down touch. */ /* * Locally do absolute value. mLastMotionY is set to the y value * of the down event. */ MotionEvent ev = event; final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { // If we don't have a valid id, the touch down wasn't on content. return null; } int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); float x = MotionEventCompat.getX(ev, pointerIndex); float dx = x - mLastMotionX; float xDiff = Math.abs(dx); float yDiff = Math.abs(MotionEventCompat.getY(ev, pointerIndex) - mLastMotionY); if (!mIsBeingDragged) { if (isListAnyPressed()) { //Log.w("JAGP","action_move 1"); mIsUnableToDrag = true; } else if (xDiff > mTouchSlop && xDiff > yDiff) { mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); mLastMotionX = x; //Log.w("JAGP","action_move 2"); return null; } else { if (yDiff > mTouchSlop) { // The finger has moved enough in the vertical // direction to be counted as a drag... abort // any attempt to drag horizontally, to work correctly // with children that have scrolling containers. //Log.w("JAGP","action_move 3"); mIsUnableToDrag = true; } } } if (mIsBeingDragged) { //Log.w("JAGP","action_move 4"); // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); x = MotionEventCompat.getX(ev, activePointerIndex); final float deltaX = mLastMotionX - x; mLastMotionX = x; float oldScrollX = getScrollX(); float scrollX = oldScrollX + deltaX; final int width = getListView().getWidth(); final int widthWithMargin = width; final float leftBound = -widthWithMargin; if (navigationOpenMode) { if (scrollX < 0) { scrollX = 0; } else if (scrollX > rightScrollBound) { // prevent too much to left scrollX = rightScrollBound; } } else { if (scrollX > 0) { scrollX = 0; } else if (scrollX > rightScrollBound) { scrollX = rightScrollBound; } } // Don't lose the rounded component mLastMotionX += scrollX - (int) scrollX; scrollToX((int) scrollX, 1); return null; } } return null; }
From source file:bhav.swipeaction.SwipeAction.java
@Override public boolean onTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); int pointerIndex; if (mReturningToStart && action == MotionEvent.ACTION_DOWN) { mReturningToStart = false;/*w ww . j av a 2 s . c o m*/ } if (!isEnabled() || mReturningToStart || canChildScrollUp() || mNestedScrollInProgress) { // Fail fast if we're not in a state where a swipe is possible return false; } switch (action) { case MotionEvent.ACTION_DOWN: mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; break; case MotionEvent.ACTION_MOVE: { pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; if (mIsBeingDragged) { if (overscrollTop > 0) { moveSpinner(overscrollTop); } else { return false; } } break; } case MotionEventCompat.ACTION_POINTER_DOWN: { pointerIndex = MotionEventCompat.getActionIndex(ev); if (pointerIndex < 0) { Log.e(TAG, "Got ACTION_POINTER_DOWN event but have an invalid action index."); return false; } mActivePointerId = MotionEventCompat.getPointerId(ev, pointerIndex); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: { pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(TAG, "Got ACTION_UP event but don't have an active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; finishSpinner(overscrollTop); mActivePointerId = INVALID_POINTER; return false; } case MotionEvent.ACTION_CANCEL: return false; } return true; }
From source file:com.jzh.stuapp.view.MyViewPager.java
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { /*/*from ww w. j a va 2 s. c om*/ * This method JUST determines whether we want to intercept the motion. * If we return true, onMotionEvent will be called and we do the actual * scrolling there. */ final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { if (DEBUG) Log.v(TAG, "Intercept done!"); mIsBeingDragged = false; mIsUnableToDrag = false; mActivePointerId = INVALID_POINTER; return false; } if (action != MotionEvent.ACTION_DOWN) { if (mIsBeingDragged) { if (DEBUG) Log.v(TAG, "Intercept returning true!"); return true; } if (mIsUnableToDrag) { if (DEBUG) Log.v(TAG, "Intercept returning false!"); return false; } } switch (action) { case MotionEvent.ACTION_MOVE: { /* * mIsBeingDragged == false, otherwise the shortcut would have * caught it. Check whether the user has moved far enough from his * original down touch. */ /* * Locally do absolute value. mLastMotionY is set to the y value of * the down event. */ final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { break; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float dx = x - mLastMotionX; final float xDiff = Math.abs(dx); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); final int scrollX = getScrollX(); final boolean atEdge = (dx > 0 && scrollX == 0) || (dx < 0 && mAdapter != null && scrollX >= (mAdapter.getCount() - 1) * getWidth() - 1); if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (canScroll(this, false, (int) dx, (int) x, (int) y)) { mInitialMotionX = mLastMotionX = x; mLastMotionY = y; return false; } if (xDiff > mTouchSlop && xDiff > yDiff) { if (DEBUG) Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); mLastMotionX = x; setScrollingCacheEnabled(true); } else { if (yDiff > mTouchSlop) { if (DEBUG) Log.v(TAG, "Starting unable to drag!"); mIsUnableToDrag = true; } } break; } case MotionEvent.ACTION_DOWN: { /* * Remember location of down touch. ACTION_DOWN always refers to * pointer index 0. */ mLastMotionX = mInitialMotionX = ev.getX(); mLastMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); if (mScrollState == SCROLL_STATE_SETTLING) { mIsBeingDragged = true; mIsUnableToDrag = false; setScrollState(SCROLL_STATE_DRAGGING); } else { completeScroll(); mIsBeingDragged = false; mIsUnableToDrag = false; } if (DEBUG) Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY + " mIsBeingDragged=" + mIsBeingDragged + "mIsUnableToDrag=" + mIsUnableToDrag); break; } case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } /* * The only time we want to intercept motion events is if we are in the * drag mode. */ return mIsBeingDragged; }
From source file:ayushi.view.customview.ViewDragHelper.java
private void saveLastMotion(MotionEvent ev) { final int pointerCount = MotionEventCompat.getPointerCount(ev); for (int i = 0; i < pointerCount; i++) { final int pointerId = MotionEventCompat.getPointerId(ev, i); final float x = MotionEventCompat.getX(ev, i); final float y = MotionEventCompat.getY(ev, i); // Sometimes we can try and save last motion for a pointer never recorded in initial motion. In this case we just discard it. if (mLastMotionX != null && mLastMotionY != null && mLastMotionX.length > pointerId && mLastMotionY.length > pointerId) { mLastMotionX[pointerId] = x; mLastMotionY[pointerId] = y; }/* ww w . java 2s . c o m*/ } }
From source file:android.improving.utils.views.swipeback.ViewDragHelper.java
private void saveLastMotion(MotionEvent ev) { final int pointerCount = MotionEventCompat.getPointerCount(ev); for (int i = 0; i < pointerCount; i++) { final int pointerId = MotionEventCompat.getPointerId(ev, i); final float x = MotionEventCompat.getX(ev, i); final float y = MotionEventCompat.getY(ev, i); mLastMotionX[pointerId] = x;/*from www . j av a 2 s . co m*/ mLastMotionY[pointerId] = y; } }
From source file:atownsend.swipeopenhelper.SwipeOpenItemTouchHelper.java
private void updateDxDy(MotionEvent ev, int directionFlags, int pointerIndex) { final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex); // Calculate the distance moved dX = x - initialTouchX;// w w w . ja v a 2 s. co m dY = y - initialTouchY; if ((directionFlags & LEFT) == 0) { dX = Math.max(0, dX); } if ((directionFlags & RIGHT) == 0) { dX = Math.min(0, dX); } if ((directionFlags & UP) == 0) { dY = Math.max(0, dY); } if ((directionFlags & DOWN) == 0) { dY = Math.min(0, dY); } }
From source file:com.callba.phone.widget.refreshlayout.RefreshLayout.java
private boolean footerInterceptTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_DOWN: mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsFooterBeingDragged = false;//from w w w . ja va2s . c om mFooterCurrPercentage = 0; break; case MotionEvent.ACTION_MOVE: if (mActivePointerId == INVALID_POINTER) { Log.e(LOG_TAG, "Got ACTION_MOVE event but don't have an active pointer id."); return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (pointerIndex < 0) { Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); return false; } final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = y - mInitialMotionY; if (yDiff < -mTouchSlop) { mLastMotionY = y; mIsFooterBeingDragged = true; } break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mIsFooterBeingDragged = false; mFooterCurrPercentage = 0; mActivePointerId = INVALID_POINTER; break; } return mIsFooterBeingDragged; }
From source file:com.mmt.widget.ViewDragHelper.java
/** * Process a touch event received by the parent view. This method will * dispatch callback events as needed before returning. The parent view's * onTouchEvent implementation should call this. * * @param ev The touch event received by the parent view *///from ww w .j ava 2 s . co m public void processTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); final int actionIndex = MotionEventCompat.getActionIndex(ev); if (action == MotionEvent.ACTION_DOWN) { // Reset things for a new event stream, just in case we didn't get // the whole previous stream. cancel(); } if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); switch (action) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); final int pointerId = MotionEventCompat.getPointerId(ev, 0); final View toCapture = findTopChildUnder((int) x, (int) y); saveInitialMotion(x, y, pointerId); // Since the parent is already directly processing this touch // event, // there is no reason to delay for a slop before dragging. // Start immediately if possible. tryCaptureViewForDrag(toCapture, pointerId); final int edgesTouched = mInitialEdgesTouched[pointerId]; if ((edgesTouched & mTrackingEdges) != 0) { mCallback.onEdgeTouched(edgesTouched & mTrackingEdges, pointerId); } break; } case MotionEventCompat.ACTION_POINTER_DOWN: { final int pointerId = MotionEventCompat.getPointerId(ev, actionIndex); final float x = MotionEventCompat.getX(ev, actionIndex); final float y = MotionEventCompat.getY(ev, actionIndex); saveInitialMotion(x, y, pointerId); // A ViewDragHelper can only manipulate one view at a time. if (mDragState == STATE_IDLE) { // If we're idle we can do anything! Treat it like a normal // down // event. final View toCapture = findTopChildUnder((int) x, (int) y); tryCaptureViewForDrag(toCapture, pointerId); final int edgesTouched = mInitialEdgesTouched[pointerId]; if ((edgesTouched & mTrackingEdges) != 0) { mCallback.onEdgeTouched(edgesTouched & mTrackingEdges, pointerId); } } else if (isCapturedViewUnder((int) x, (int) y)) { // We're still tracking a captured view. If the same view is // under this // point, we'll swap to controlling it with this pointer // instead. // (This will still work if we're "catching" a settling // view.) tryCaptureViewForDrag(mCapturedView, pointerId); } break; } case MotionEvent.ACTION_MOVE: { if (mDragState == STATE_DRAGGING) { final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, index); final float y = MotionEventCompat.getY(ev, index); final int idx = (int) (x - mLastMotionX[mActivePointerId]); final int idy = (int) (y - mLastMotionY[mActivePointerId]); dragTo(mCapturedView.getLeft() + idx, mCapturedView.getTop() + idy, idx, idy); saveLastMotion(ev); } else { // Check to see if any pointer is now over a draggable view. final int pointerCount = MotionEventCompat.getPointerCount(ev); for (int i = 0; i < pointerCount; i++) { final int pointerId = MotionEventCompat.getPointerId(ev, i); final float x = MotionEventCompat.getX(ev, i); final float y = MotionEventCompat.getY(ev, i); final float dx = x - mInitialMotionX[pointerId]; final float dy = y - mInitialMotionY[pointerId]; reportNewEdgeDrags(dx, dy, pointerId); if (mDragState == STATE_DRAGGING) { // Callback might have started an edge drag. break; } final View toCapture = findTopChildUnder((int) x, (int) y); if (checkTouchSlop(toCapture, dx, dy) && tryCaptureViewForDrag(toCapture, pointerId)) { break; } } saveLastMotion(ev); } break; } case MotionEventCompat.ACTION_POINTER_UP: { final int pointerId = MotionEventCompat.getPointerId(ev, actionIndex); if (mDragState == STATE_DRAGGING && pointerId == mActivePointerId) { // Try to find another pointer that's still holding on to // the // captured view. int newActivePointer = INVALID_POINTER; final int pointerCount = MotionEventCompat.getPointerCount(ev); for (int i = 0; i < pointerCount; i++) { final int id = MotionEventCompat.getPointerId(ev, i); if (id == mActivePointerId) { // This one's going away, skip. continue; } final float x = MotionEventCompat.getX(ev, i); final float y = MotionEventCompat.getY(ev, i); if (findTopChildUnder((int) x, (int) y) == mCapturedView && tryCaptureViewForDrag(mCapturedView, id)) { newActivePointer = mActivePointerId; break; } } if (newActivePointer == INVALID_POINTER) { // We didn't find another pointer still touching the // view, // release it. releaseViewForPointerUp(); } } clearMotionHistory(pointerId); break; } case MotionEvent.ACTION_UP: { if (mDragState == STATE_DRAGGING) { releaseViewForPointerUp(); } cancel(); break; } case MotionEvent.ACTION_CANCEL: { if (mDragState == STATE_DRAGGING) { dispatchViewReleased(0, 0); } cancel(); break; } } }