List of usage examples for android.view MotionEvent getAction
public final int getAction()
From source file:com.android.leanlauncher.Workspace.java
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: break;//from w ww. j a va 2 s . c o m case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_UP: if (mTouchState == PagedView.TOUCH_STATE_REST) { final CellLayout currentPage = mWorkspace; if (currentPage != null) { onWallpaperTap(ev); } } } return super.onInterceptTouchEvent(ev); }
From source file:beichen.douban.ui.view.LazyViewPager.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (mFakeDragging) { // A fake drag is in progress already, ignore this real one // but still eat the touch events. // (It is likely that the user is multi-touching the screen.) return true; }//from w ww .j a v a 2 s.co m 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; } if (mAdapter == null || mAdapter.getCount() == 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: { /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ completeScroll(); // Remember where the motion event started mLastMotionX = mInitialMotionX = ev.getX(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; } case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastMotionX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (xDiff > mTouchSlop && xDiff > yDiff) { if (DEBUG) Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; mLastMotionX = x; setScrollState(SCROLL_STATE_DRAGGING); setScrollingCacheEnabled(true); } } if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, activePointerIndex); final float deltaX = mLastMotionX - x; mLastMotionX = x; float oldScrollX = getScrollX(); float scrollX = oldScrollX + deltaX; final int width = getWidth(); final int widthWithMargin = width + mPageMargin; final int lastItemIndex = mAdapter.getCount() - 1; final float leftBound = Math.max(0, (mCurItem - 1) * widthWithMargin); final float rightBound = Math.min(mCurItem + 1, lastItemIndex) * widthWithMargin; if (scrollX < leftBound) { if (leftBound == 0) { float over = -scrollX; needsInvalidate = mLeftEdge.onPull(over / width); } scrollX = leftBound; } else if (scrollX > rightBound) { if (rightBound == lastItemIndex * widthWithMargin) { float over = scrollX - rightBound; needsInvalidate = mRightEdge.onPull(over / width); } scrollX = rightBound; } // Don't lose the rounded component mLastMotionX += scrollX - (int) scrollX; scrollTo((int) scrollX, getScrollY()); pageScrolled((int) scrollX); } break; case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId); mPopulatePending = true; final int widthWithMargin = getWidth() + mPageMargin; final int scrollX = getScrollX(); final int currentPage = scrollX / widthWithMargin; final float pageOffset = (float) (scrollX % widthWithMargin) / widthWithMargin; final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, activePointerIndex); final int totalDelta = (int) (x - mInitialMotionX); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); mActivePointerId = INVALID_POINTER; endDrag(); needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); } break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { setCurrentItemInternal(mCurItem, true, true); mActivePointerId = INVALID_POINTER; endDrag(); needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease(); } 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) { invalidate(); } return true; }
From source file:com.android.launcher2.PagedView.java
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { /*/*from ww w . j av a 2s. c o m*/ * This method JUST determines whether we want to intercept the motion. * If we return true, onTouchEvent will be called and we do the actual * scrolling there. */ acquireVelocityTrackerAndAddMovement(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev); /* * Shortcut the most recurring case: the user is in the dragging * state and he is moving his finger. We want to intercept this * motion. */ final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mTouchState == TOUCH_STATE_SCROLLING)) { return true; } switch (action & MotionEvent.ACTION_MASK) { 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. */ if (mActivePointerId != INVALID_POINTER) { determineScrollingStart(ev); break; } // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN // event. in that case, treat the first occurence of a move event as a ACTION_DOWN // i.e. fall through to the next case (don't break) // (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events // while it's small- this was causing a crash before we checked for INVALID_POINTER) } case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); // Remember location of down touch mDownMotionX = x; mLastMotionX = x; mLastMotionY = y; mLastMotionXRemainder = 0; mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); mAllowLongPress = true; /* * If being flinged and user touches the screen, initiate drag; * otherwise don't. mScroller.isFinished should be false when * being flinged. */ final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX()); final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop); if (finishedScrolling) { mTouchState = TOUCH_STATE_REST; mScroller.abortAnimation(); } else { mTouchState = TOUCH_STATE_SCROLLING; } // check if this can be the beginning of a tap on the side of the pages // to scroll the current page if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) { if (getChildCount() > 0) { if (hitsPreviousPage(x, y)) { mTouchState = TOUCH_STATE_PREV_PAGE; } else if (hitsNextPage(x, y)) { mTouchState = TOUCH_STATE_NEXT_PAGE; } } } break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; mAllowLongPress = false; mActivePointerId = INVALID_POINTER; releaseVelocityTracker(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); releaseVelocityTracker(); break; } /* * The only time we want to intercept motion events is if we are in the * drag mode. */ return mTouchState != TOUCH_STATE_REST; }
From source file:com.example.SmartBoard.DrawingView.java
@Override public boolean onTouchEvent(MotionEvent event) { //detect user touch float touchX = event.getX(); float touchY = event.getY(); //System.out.println("X"+touchX); // System.out.println("Y"+touchY); if (rectMode) { onTouchRectangleMode(event);/*from ww w . j a v a 2 s . c o m*/ return true; } else if (circleMode) { onTouchCircleMode(event); return true; } else if (lineMode) { onTouchLineMode(event); return true; } else if (textMode) { onTouchTextMode(event); return true; } else if (dragMode) { onTouchDragEvent(event); return true; } else if (removeObjectMode) { onRemoveObjectEvent(event); return true; } else if (colorDropperMode) { onTouchColorDropperMode(event); return true; } else if (textSizeMode) { onTouchTextResizeEvent(event); return true; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: drawPath.moveTo(touchX, touchY); break; case MotionEvent.ACTION_MOVE: drawPath.lineTo(touchX, touchY); break; case MotionEvent.ACTION_UP: drawCanvas.drawPath(drawPath, drawPaint); drawPath.reset(); break; default: return false; } //System.out.println(mqtt); invalidate(); mqtt.publish(touchX, touchY, event.getAction(), paintColor, mode, strokeWidth); return true; }
From source file:com.android.contacts.quickcontact.QuickContactActivity.java
@Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { TouchPointManager.getInstance().setPoint((int) ev.getRawX(), (int) ev.getRawY()); }//from w w w .j a va 2 s . c o m return super.dispatchTouchEvent(ev); }
From source file:com.biznow.ordernow.fragments.StaggeredGridView.java
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { mVelocityTracker.addMovement(ev);//w ww . ja va2 s . co m final int action = ev.getAction() & MotionEventCompat.ACTION_MASK; switch (action) { case MotionEvent.ACTION_DOWN: mVelocityTracker.clear(); mScroller.abortAnimation(); mLastTouchY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mTouchRemainderY = 0; if (mTouchMode == TOUCH_MODE_FLINGING) { // Catch! mTouchMode = TOUCH_MODE_DRAGGING; return true; } break; case MotionEvent.ACTION_MOVE: { final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId); if (index < 0) { Utilities.error(TAG + " onInterceptTouchEvent could not find pointer with id " + mActivePointerId + " - did StaggeredGridView receive an inconsistent " + "event stream?"); return false; } final float y = MotionEventCompat.getY(ev, index); final float dy = y - mLastTouchY + mTouchRemainderY; final int deltaY = (int) dy; mTouchRemainderY = dy - deltaY; if (Math.abs(dy) > mTouchSlop) { mTouchMode = TOUCH_MODE_DRAGGING; return true; } } } return false; }
From source file:administrator.example.com.myscrollview.VerticalViewPager.java
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { /*/*from w ww. j a va 2 s.c o m*/ * 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; // Always take care of the touch gesture being complete. if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { // Release the drag. if (DEBUG) Log.v(TAG, "Intercept done!"); mIsBeingDragged = false; mIsUnableToDrag = false; mActivePointerId = INVALID_POINTER; if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } /* end of if */ return false; } /* end of if */ // Nothing more to do here if we have decided whether or not we // are dragging. if (action != MotionEvent.ACTION_DOWN) { if (mIsBeingDragged) { if (DEBUG) Log.v(TAG, "Intercept returning true!"); return true; } /* end of if */ if (mIsUnableToDrag) { if (DEBUG) Log.v(TAG, "Intercept returning false!"); return false; } /* end of if */ } /* end of if */ 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. mLastMotionX is set to the x value * of the down event. */ final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { // If we don't have a valid id, the touch down wasn't on content. break; } /* end of if */ final int pointerIndex = MotionEventCompat.findPointerIndex(ev, activePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastMotionX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float dy = y - mLastMotionY; final float yDiff = Math.abs(dy); if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (canScroll(this, false, (int) dy, (int) x, (int) y)) { // Nested view has scrollable area under this point. Let it be handled there. mInitialMotionY = mLastMotionY = y; mLastMotionX = x; return false; } /* end of if */ if (yDiff > mTouchSlop && yDiff > xDiff) { if (DEBUG) Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); mLastMotionY = y; setScrollingCacheEnabled(true); } else { if (xDiff > mTouchSlop) { // The finger has moved enough in the horizontal // direction to be counted as a drag... abort // any attempt to drag vertically, to work correctly // with children that have scrolling containers. if (DEBUG) Log.v(TAG, "Starting unable to drag!"); mIsUnableToDrag = true; } /* end of if */ } /* end of if */ break; } /* end of case */ case MotionEvent.ACTION_DOWN: { /* * Remember location of down touch. * ACTION_DOWN always refers to pointer index 0. */ mLastMotionX = ev.getX(); mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); if (mScrollState == SCROLL_STATE_SETTLING) { // Let the user 'catch' the pager as it animates. mIsBeingDragged = true; mIsUnableToDrag = false; setScrollState(SCROLL_STATE_DRAGGING); } else { completeScroll(); mIsBeingDragged = false; mIsUnableToDrag = false; } /* end of if */ if (DEBUG) Log.v(TAG, "Down at " + mLastMotionX + "," + mLastMotionY + " mIsBeingDragged=" + mIsBeingDragged + "mIsUnableToDrag=" + mIsUnableToDrag); break; } /* end of case */ case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; } /* end of switch */ if (!mIsBeingDragged) { // Track the velocity as long as we aren't dragging. // Once we start a real drag we will track in onTouchEvent. if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } /* end of if */ mVelocityTracker.addMovement(ev); } /* end of if */ /* * The only time we want to intercept motion events is if we are in the * drag mode. */ return mIsBeingDragged; }
From source file:xiaofan.llongimageview.view.SubsamplingScaleImageView.java
/** * Handle touch events. One finger pans, and two finger pinch and zoom plus panning. *//*from w w w . j av a 2 s . c o m*/ @Override public boolean onTouchEvent(MotionEvent event) { PointF vCenterEnd; float vDistEnd; // During non-interruptible anims, ignore all touch events if (anim != null && !anim.interruptible) { getParent().requestDisallowInterceptTouchEvent(true); return true; } else { anim = null; } // Abort if not ready if (vTranslate == null) { return true; } // Detect flings, taps and double taps if (detector == null || detector.onTouchEvent(event)) { return true; } int touchCount = event.getPointerCount(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_1_DOWN: case MotionEvent.ACTION_POINTER_2_DOWN: anim = null; getParent().requestDisallowInterceptTouchEvent(true); maxTouchCount = Math.max(maxTouchCount, touchCount); if (touchCount >= 2) { if (zoomEnabled) { // Start pinch to zoom. Calculate distance between touch points and center point of the pinch. float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1)); scaleStart = scale; vDistStart = distance; vTranslateStart = new PointF(vTranslate.x, vTranslate.y); vCenterStart = new PointF((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2); } else { // Abort all gestures on second touch maxTouchCount = 0; } // Cancel long click timer handler.removeMessages(MESSAGE_LONG_CLICK); } else { // Start one-finger pan vTranslateStart = new PointF(vTranslate.x, vTranslate.y); vCenterStart = new PointF(event.getX(), event.getY()); // Start long click timer handler.sendEmptyMessageDelayed(MESSAGE_LONG_CLICK, 600); } return true; case MotionEvent.ACTION_MOVE: boolean consumed = false; if (maxTouchCount > 0) { if (touchCount >= 2) { // Calculate new distance between touch points, to scale and pan relative to start values. vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1)); vCenterEnd = new PointF((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2); if (zoomEnabled && (distance(vCenterStart.x, vCenterEnd.x, vCenterStart.y, vCenterEnd.y) > 5 || Math.abs(vDistEnd - vDistStart) > 5 || isPanning)) { isZooming = true; isPanning = true; consumed = true; scale = Math.min(maxScale, (vDistEnd / vDistStart) * scaleStart); if (scale <= minScale()) { // Minimum scale reached so don't pan. Adjust start settings so any expand will zoom in. vDistStart = vDistEnd; scaleStart = minScale(); vCenterStart = vCenterEnd; vTranslateStart = vTranslate; } else if (panEnabled) { // Translate to place the source image coordinate that was at the center of the pinch at the start // at the center of the pinch now, to give simultaneous pan + zoom. float vLeftStart = vCenterStart.x - vTranslateStart.x; float vTopStart = vCenterStart.y - vTranslateStart.y; float vLeftNow = vLeftStart * (scale / scaleStart); float vTopNow = vTopStart * (scale / scaleStart); vTranslate.x = vCenterEnd.x - vLeftNow; vTranslate.y = vCenterEnd.y - vTopNow; } else if (sRequestedCenter != null) { // With a center specified from code, zoom around that point. vTranslate.x = (getWidth() / 2) - (scale * sRequestedCenter.x); vTranslate.y = (getHeight() / 2) - (scale * sRequestedCenter.y); } else { // With no requested center, scale around the image center. vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2)); vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2)); } fitToBounds(true); refreshRequiredTiles(false); } } else if (!isZooming) { // One finger pan - translate the image. We do this calculation even with pan disabled so click // and long click behaviour is preserved. float dx = Math.abs(event.getX() - vCenterStart.x); float dy = Math.abs(event.getY() - vCenterStart.y); if (dx > 5 || dy > 5 || isPanning) { consumed = true; vTranslate.x = vTranslateStart.x + (event.getX() - vCenterStart.x); vTranslate.y = vTranslateStart.y + (event.getY() - vCenterStart.y); float lastX = vTranslate.x; float lastY = vTranslate.y; fitToBounds(true); if (lastX == vTranslate.x || (lastY == vTranslate.y && dy > 10) || isPanning) { isPanning = true; } else if (dx > 5) { // Haven't panned the image, and we're at the left or right edge. Switch to page swipe. maxTouchCount = 0; handler.removeMessages(MESSAGE_LONG_CLICK); getParent().requestDisallowInterceptTouchEvent(false); } if (!panEnabled) { vTranslate.x = vTranslateStart.x; vTranslate.y = vTranslateStart.y; getParent().requestDisallowInterceptTouchEvent(false); } refreshRequiredTiles(false); } } } if (consumed) { handler.removeMessages(MESSAGE_LONG_CLICK); invalidate(); return true; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_2_UP: handler.removeMessages(MESSAGE_LONG_CLICK); if (maxTouchCount > 0 && (isZooming || isPanning)) { if (isZooming && touchCount == 2) { // Convert from zoom to pan with remaining touch isPanning = true; vTranslateStart = new PointF(vTranslate.x, vTranslate.y); if (event.getActionIndex() == 1) { vCenterStart = new PointF(event.getX(0), event.getY(0)); } else { vCenterStart = new PointF(event.getX(1), event.getY(1)); } } if (touchCount < 3) { // End zooming when only one touch point isZooming = false; } if (touchCount < 2) { // End panning when no touch points isPanning = false; maxTouchCount = 0; } // Trigger load of tiles now required refreshRequiredTiles(true); return true; } if (touchCount == 1) { isZooming = false; isPanning = false; maxTouchCount = 0; } return true; } return super.onTouchEvent(event); }
From source file:administrator.example.com.myscrollview.VerticalViewPager.java
@Override public boolean onTouchEvent(MotionEvent ev) { if (mFakeDragging) { // A fake drag is in progress already, ignore this real one // but still eat the touch events. // (It is likely that the user is multi-touching the screen.) return true; } /* end of if */ 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; } /* end of if */ if (mAdapter == null || mAdapter.getCount() == 0) { // Nothing to present or scroll; nothing to touch. return false; } /* end of if */ if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } /* end of if */ mVelocityTracker.addMovement(ev);/*from w ww . java 2 s .c o m*/ final int action = ev.getAction(); boolean needsInvalidate = false; switch (action & MotionEventCompat.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { /* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */ completeScroll(); // Remember where the motion event started mLastMotionY = mInitialMotionY = ev.getY(); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); break; } /* end of case */ case MotionEvent.ACTION_MOVE: if (!mIsBeingDragged) { final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex); final float xDiff = Math.abs(x - mLastMotionX); final float y = MotionEventCompat.getY(ev, pointerIndex); final float yDiff = Math.abs(y - mLastMotionY); if (DEBUG) Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff); if (yDiff > mTouchSlop && yDiff > xDiff) { if (DEBUG) Log.v(TAG, "Starting drag!"); mIsBeingDragged = true; mLastMotionY = y; setScrollState(SCROLL_STATE_DRAGGING); setScrollingCacheEnabled(true); } /* end of if */ } /* end of if */ if (mIsBeingDragged) { // Scroll to follow the motion event final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, activePointerIndex); final float deltaY = mLastMotionY - y; mLastMotionY = y; float oldScrollY = getScrollY(); float scrollY = oldScrollY + deltaY; final int height = getHeight(); final int heightWithMargin = height + mPageMargin; final int lastItemIndex = mAdapter.getCount() - 1; final float topBound = Math.max(0, (mCurItem - 1) * heightWithMargin); final float bottomBound = Math.min(mCurItem + 1, lastItemIndex) * heightWithMargin; if (scrollY < topBound) { if (topBound == 0) { float over = -scrollY; needsInvalidate = mTopEdge.onPull(over / height); } /* end of if */ scrollY = topBound; } else if (scrollY > bottomBound) { if (bottomBound == lastItemIndex * heightWithMargin) { float over = scrollY - bottomBound; needsInvalidate = mBottomEdge.onPull(over / height); } /* end of if */ scrollY = bottomBound; } /* end of if */ // Don't lose the rounded component mLastMotionY += scrollY - (int) scrollY; scrollTo(getScrollX(), (int) scrollY); pageScrolled((int) scrollY); } /* end of if */ break; case MotionEvent.ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId); mPopulatePending = true; final int heightWithMargin = getHeight() + mPageMargin; final int scrollY = getScrollY(); final int currentPage = scrollY / heightWithMargin; final float pageOffset = (float) (scrollY % heightWithMargin) / heightWithMargin; final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, activePointerIndex); final int totalDelta = (int) (y - mInitialMotionY); int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity, totalDelta); setCurrentItemInternal(nextPage, true, true, initialVelocity); mActivePointerId = INVALID_POINTER; endDrag(); needsInvalidate = mTopEdge.onRelease() | mBottomEdge.onRelease(); } /* end of if */ break; case MotionEvent.ACTION_CANCEL: if (mIsBeingDragged) { setCurrentItemInternal(mCurItem, true, true); mActivePointerId = INVALID_POINTER; endDrag(); needsInvalidate = mTopEdge.onRelease() | mBottomEdge.onRelease(); } /* end of if */ break; case MotionEventCompat.ACTION_POINTER_DOWN: { final int index = MotionEventCompat.getActionIndex(ev); final float y = MotionEventCompat.getY(ev, index); mLastMotionY = y; mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; } /* end of case */ case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); mLastMotionY = MotionEventCompat.getY(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId)); break; } /* end of switch */ if (needsInvalidate) { invalidate(); } /* end of if */ return true; }