Example usage for android.support.v4.view MotionEventCompat getActionMasked

List of usage examples for android.support.v4.view MotionEventCompat getActionMasked

Introduction

In this page you can find the example usage for android.support.v4.view MotionEventCompat getActionMasked.

Prototype

public static int getActionMasked(MotionEvent event) 

Source Link

Document

Call MotionEvent#getAction , returning only the #ACTION_MASK portion.

Usage

From source file:android.support.v7.widget.RecyclerView.java

@Override
public boolean onTouchEvent(MotionEvent e) {
    if (dispatchOnItemTouch(e)) {
        cancelTouch();//from  www. j  a  v  a  2 s.co  m
        return true;
    }

    final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
    final boolean canScrollVertically = mLayout.canScrollVertically();

    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(e);

    final int action = MotionEventCompat.getActionMasked(e);
    final int actionIndex = MotionEventCompat.getActionIndex(e);

    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        mScrollPointerId = MotionEventCompat.getPointerId(e, 0);
        mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f);
        mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);
    }
        break;

    case MotionEventCompat.ACTION_POINTER_DOWN: {
        mScrollPointerId = MotionEventCompat.getPointerId(e, actionIndex);
        mInitialTouchX = mLastTouchX = (int) (MotionEventCompat.getX(e, actionIndex) + 0.5f);
        mInitialTouchY = mLastTouchY = (int) (MotionEventCompat.getY(e, actionIndex) + 0.5f);
    }
        break;

    case MotionEvent.ACTION_MOVE: {
        final int index = MotionEventCompat.findPointerIndex(e, mScrollPointerId);
        if (index < 0) {
            Log.e(TAG, "Error processing scroll; pointer index for id " + mScrollPointerId
                    + " not found. Did any MotionEvents get skipped?");
            return false;
        }

        final int x = (int) (MotionEventCompat.getX(e, index) + 0.5f);
        final int y = (int) (MotionEventCompat.getY(e, index) + 0.5f);
        if (mScrollState != SCROLL_STATE_DRAGGING) {
            final int dx = x - mInitialTouchX;
            final int dy = y - mInitialTouchY;
            boolean startScroll = false;
            if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) {
                mLastTouchX = mInitialTouchX + mTouchSlop * (dx < 0 ? -1 : 1);
                startScroll = true;
            }
            if (canScrollVertically && Math.abs(dy) > mTouchSlop) {
                mLastTouchY = mInitialTouchY + mTouchSlop * (dy < 0 ? -1 : 1);
                startScroll = true;
            }
            if (startScroll) {
                getParent().requestDisallowInterceptTouchEvent(true);
                setScrollState(SCROLL_STATE_DRAGGING);
            }
        }
        if (mScrollState == SCROLL_STATE_DRAGGING) {
            final int dx = x - mLastTouchX;
            final int dy = y - mLastTouchY;
            scrollByInternal(canScrollHorizontally ? -dx : 0, canScrollVertically ? -dy : 0);
        }
        mLastTouchX = x;
        mLastTouchY = y;
    }
        break;

    case MotionEventCompat.ACTION_POINTER_UP: {
        onPointerUp(e);
    }
        break;

    case MotionEvent.ACTION_UP: {
        mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
        final float xvel = canScrollHorizontally
                ? -VelocityTrackerCompat.getXVelocity(mVelocityTracker, mScrollPointerId)
                : 0;
        final float yvel = canScrollVertically
                ? -VelocityTrackerCompat.getYVelocity(mVelocityTracker, mScrollPointerId)
                : 0;
        if (!((xvel != 0 || yvel != 0) && fling((int) xvel, (int) yvel))) {
            setScrollState(SCROLL_STATE_IDLE);
        }
        mVelocityTracker.clear();
        releaseGlows();
    }
        break;

    case MotionEvent.ACTION_CANCEL: {
        cancelTouch();
    }
        break;
    }

    return true;
}

From source file:com.hippo.refreshlayout.RefreshLayout.java

private boolean headerTouchEvent(MotionEvent ev) {
    int pointerIndex;
    final int action = MotionEventCompat.getActionMasked(ev);
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mActivePointerId = ev.getPointerId(0);
        mIsHeaderBeingDragged = false;//from   ww  w  . ja v  a 2s  .  com
        break;

    case MotionEvent.ACTION_MOVE: {
        pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex < 0) {
            Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id.");
            return false;
        }

        final float y = ev.getY(pointerIndex);
        startHeaderDragging(y);

        if (mIsHeaderBeingDragged) {
            final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
            if (overscrollTop > 0) {
                moveSpinner(overscrollTop);
            } else {
                return false;
            }
        }
        break;
    }
    case MotionEventCompat.ACTION_POINTER_DOWN: {
        pointerIndex = MotionEventCompat.getActionIndex(ev);
        if (pointerIndex < 0) {
            Log.e(LOG_TAG, "Got ACTION_POINTER_DOWN event but have an invalid action index.");
            return false;
        }
        mActivePointerId = ev.getPointerId(pointerIndex);
        break;
    }

    case MotionEventCompat.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        break;

    case MotionEvent.ACTION_UP: {
        pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex < 0) {
            Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
            return false;
        }

        if (mIsHeaderBeingDragged) {
            final float y = ev.getY(pointerIndex);
            final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
            mIsHeaderBeingDragged = false;
            finishSpinner(overscrollTop);
        }
        mActivePointerId = INVALID_POINTER;
        return false;
    }
    case MotionEvent.ACTION_CANCEL:
        pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex < 0) {
            Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
            return false;
        }

        if (mIsHeaderBeingDragged) {
            mIsHeaderBeingDragged = false;
            finishSpinner(0);
        }
        mActivePointerId = INVALID_POINTER;
        return false;
    }

    return true;
}

From source file:com.doubleTwist.drawerlib.ADrawerLayout.java

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (!mDrawerState.mDraggingEnabled)
        return false;

    final int action = MotionEventCompat.getActionMasked(ev);

    if (action == MotionEvent.ACTION_DOWN)
        mRequestDisallowIntercept = false;

    if (mRequestDisallowIntercept)
        return false;

    if (mVelocityTracker != null)
        mVelocityTracker.addMovement(ev);

    if (mDrawerState.mScrollState != IDLE)
        return true;

    // Always handle the case of the touch gesture being complete.
    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        if (DEBUG_TOUCH)
            Log.d(TAG, "UP OR CANCEL: RELEASING SCROLL");
        mIsScrolling = false;/*from   www. j  a  va  2s .  c o  m*/
        mVelocityTracker.clear();
        if (action == MotionEvent.ACTION_UP) {
            processIdleUp(ev);
        }
        mRequestDisallowIntercept = false;
        return false; // Do not intercept touch event, let the child handle it
    }

    int drawer = preProcessScrollMotionEvent(ev);
    boolean intercept = drawer >= 0;
    boolean aDrawerIsOpen = mDrawerState.mScrollState == IDLE && mDrawerState.mActiveDrawer != NO_DRAWER;

    // Let touches go through if they are in the area of an open drawer
    if (!intercept && aDrawerIsOpen) {
        if (touchIsInDrawerArea(mDrawerState.mActiveDrawer, ev)) {
            if (DEBUG_TOUCH)
                Log.d(TAG, "NOT INTERCEPTING BECAUSE A DRAWER IS OPEN");
            return false;
        }
    }

    postProcessScrollMotionEvent(drawer, ev);

    if (DEBUG_TOUCH)
        Log.d(TAG, "intercept/aDrawerIsOpen: " + intercept + "/" + aDrawerIsOpen);

    // Intercept events unless we are in the initial idle position
    return intercept || aDrawerIsOpen;
}

From source file:com.hippo.refreshlayout.RefreshLayout.java

private boolean footerTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    int pointerIndex;
    float y;/*from w w  w  .j a v  a  2 s  .  co m*/
    float yDiff;
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mActivePointerId = ev.getPointerId(0);
        mIsFooterBeingDragged = false;
        mFooterCurrPercentage = 0;
        break;

    case MotionEvent.ACTION_MOVE:
        pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex < 0) {
            Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id.");
            return false;
        }

        y = ev.getY(pointerIndex);
        if (!mIsFooterBeingDragged) {
            yDiff = y - mInitialDownY;
            if (yDiff < -mTouchSlop) {
                mIsFooterBeingDragged = true;
                mInitialMotionY = mInitialDownY - mTouchSlop;
            }
        }

        if (mIsFooterBeingDragged) {
            yDiff = y - mInitialMotionY;
            setTriggerPercentage(mAccelerateInterpolator.getInterpolation(
                    MathUtils.clamp(-yDiff, 0, mFooterDistanceToTriggerSync) / mFooterDistanceToTriggerSync));
        }
        break;

    case MotionEventCompat.ACTION_POINTER_DOWN: {
        final int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = ev.getPointerId(index);
        break;
    }

    case MotionEventCompat.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        break;

    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (mActivePointerId == INVALID_POINTER && pointerIndex < 0) {
            if (action == MotionEvent.ACTION_UP) {
                Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
            }
            return false;
        }

        try {
            y = ev.getY(pointerIndex);
        } catch (Throwable e) {
            y = 0;
        }

        yDiff = y - mInitialMotionY;

        if (action == MotionEvent.ACTION_UP && -yDiff > mFooterDistanceToTriggerSync) {
            // User movement passed distance; trigger a refresh
            startFooterRefresh();
        } else {
            mCancel.run();
        }

        mIsFooterBeingDragged = false;
        mFooterCurrPercentage = 0;
        mActivePointerId = INVALID_POINTER;
        return false;
    }

    return mIsFooterBeingDragged;
}

From source file:com.nttec.everychan.ui.gallery.GalleryActivity.java

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (fullscreenCallback != null) {
        fullscreenCallback.keepUI(MotionEventCompat.getActionMasked(ev) == MotionEvent.ACTION_UP);
        fullscreenGestureDetector.onTouchEvent(ev);
    }//from w w  w . java 2 s  . c om
    return super.dispatchTouchEvent(ev);
}

From source file:com.doubleTwist.drawerlib.ADrawerLayout.java

private int preProcessScrollMotionEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    switch (action) {
    case MotionEvent.ACTION_DOWN:
        if (DEBUG_TOUCH)
            Log.d(TAG, "DOWN: " + ev.getX(0) + "," + ev.getY(0));
        if (!mIsScrolling) {
            mVelocityTracker.clear();/*from   www  . j  a v a  2  s .  c  o m*/
            mDownEvent.mCoords.x = ev.getX(0);
            mDownEvent.mCoords.y = ev.getY(0);
            mDownEvent.mPointerId = ev.getPointerId(0);
            if (DEBUG_TOUCH)
                Log.d(TAG, "SAVED: " + ev.getX(0) + "," + ev.getY(0));
        }
        break;
    case MotionEvent.ACTION_MOVE: {
        final int ptrIdx = ev.findPointerIndex(mDownEvent.mPointerId);
        if (ptrIdx < 0 || ptrIdx >= ev.getPointerCount())
            return -1;

        if (DEBUG_TOUCH)
            Log.d(TAG, "MOVE: " + ev.getX(ptrIdx) + "," + ev.getY(ptrIdx));
        if (mIsScrolling) {
            return mDrawerState.mActiveDrawer;
        }

        // If the user has dragged her finger horizontally more than
        // the touch slop, start the scroll

        final float xDiff = calculateDistanceX(ev, mDownEvent);
        final float yDiff = calculateDistanceY(ev, mDownEvent);
        final float dxAbs = Math.abs(xDiff);
        final float dyAbs = Math.abs(yDiff);

        if (DEBUG_TOUCH) {
            Log.d(TAG, "xDiff: " + xDiff + " -- " + ev.getX(ptrIdx) + " -- " + mDownEvent.mCoords.x);
            Log.d(TAG, "xDiff/yDiff/dxAbs/dyAbs: " + xDiff + "/" + yDiff + "/" + dxAbs + "/" + dyAbs);
            Log.d(TAG, "canScrollX/canScrollY: " + canScroll(MotionEvent.AXIS_X, xDiff) + "/"
                    + canScroll(MotionEvent.AXIS_Y, yDiff));
            Log.d(TAG, "activeDrawer/scrollState: " + mDrawerState.mActiveDrawer + "/"
                    + mDrawerState.mScrollState);
        }

        if (dxAbs > dyAbs && dxAbs > mTouchSlop && canScroll(MotionEvent.AXIS_X, xDiff)) {
            if (DEBUG_TOUCH)
                Log.d(TAG, "X axis branch");
            int drawer;
            if (mDrawerState.mActiveDrawer == NO_DRAWER)
                drawer = xDiff > 0 ? LEFT_DRAWER : RIGHT_DRAWER;
            else
                drawer = mDrawerState.mActiveDrawer;
            if (!isInitialPositionValidForDrawer(mDownEvent, drawer))
                drawer = -1;
            return drawer;
        }

        if (dyAbs > dxAbs && dyAbs > mTouchSlop && canScroll(MotionEvent.AXIS_Y, yDiff)) {
            if (DEBUG_TOUCH)
                Log.d(TAG, "Y axis branch");
            int drawer;
            if (mDrawerState.mActiveDrawer == NO_DRAWER)
                drawer = yDiff > 0 ? TOP_DRAWER : BOTTOM_DRAWER;
            else
                drawer = mDrawerState.mActiveDrawer;

            if (!isInitialPositionValidForDrawer(mDownEvent, drawer))
                drawer = -1;
            return drawer;
        }

        break;
    }
    }
    return -1;
}

From source file:com.jecelyin.editor.v2.widget.AnyDrawerLayout.java

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    // "|" used deliberately here; both methods should be invoked.
    final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev)
            | mRightDragger.shouldInterceptTouchEvent(ev) | mBottomDragger.shouldInterceptTouchEvent(ev);

    boolean interceptForTap = false;

    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();
        mInitialMotionX = x;//from  w  w w .ja v a2s. c o m
        mInitialMotionY = y;
        if (mScrimOpacity > 0) {
            final View child = mLeftDragger.findTopChildUnder((int) x, (int) y);
            if (child != null && isContentView(child)) {
                interceptForTap = true;
            }
        }
        mDisallowInterceptRequested = false;
        mChildrenCanceledTouch = false;
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        // If we cross the touch slop, don't perform the delayed peek for an edge touch.
        if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) {
            mLeftCallback.removeCallbacks();
            mRightCallback.removeCallbacks();
            mBottomCallback.removeCallbacks();
        }
        break;
    }

    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP: {
        mDisallowInterceptRequested = false;
        mChildrenCanceledTouch = false;
    }
    }

    return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch;
}

From source file:com.anysoftkeyboard.keyboards.views.AnyKeyboardViewBase.java

@Override
public boolean onTouchEvent(@NonNull MotionEvent nativeMotionEvent) {
    if (mKeyboard == null)//I mean, if there isn't any keyboard I'm handling, what's the point?
        return false;

    final int action = MotionEventCompat.getActionMasked(nativeMotionEvent);
    final int pointerCount = MotionEventCompat.getPointerCount(nativeMotionEvent);
    if (pointerCount > 1)
        mLastTimeHadTwoFingers = SystemClock.elapsedRealtime();//marking the time. Read isAtTwoFingersState()

    if (mTouchesAreDisabledTillLastFingerIsUp) {
        if (!areTouchesDisabled(nativeMotionEvent)/*this means it was just reset*/) {
            mTouchesAreDisabledTillLastFingerIsUp = false;
            //continue with onTouchEvent flow.
            if (action != MotionEvent.ACTION_DOWN) {
                //swallowing the event.
                //in case this is a DOWN event, we do want to pass it
                return true;
            }//from  www .j a  v  a 2  s.  co m
        } else {
            //swallowing touch event until we reset mTouchesAreDisabledTillLastFingerIsUp
            return true;
        }
    }

    final long eventTime = nativeMotionEvent.getEventTime();
    final int index = MotionEventCompat.getActionIndex(nativeMotionEvent);
    final int id = nativeMotionEvent.getPointerId(index);
    final int x = (int) nativeMotionEvent.getX(index);
    final int y = (int) nativeMotionEvent.getY(index);

    if (mKeyPressTimingHandler.isInKeyRepeat()) {
        // It will keep being in the key repeating mode while the key is
        // being pressed.
        if (action == MotionEvent.ACTION_MOVE) {
            return true;
        }
        final PointerTracker tracker = getPointerTracker(id);
        // Key repeating timer will be canceled if 2 or more keys are in
        // action, and current
        // event (UP or DOWN) is non-modifier key.
        if (pointerCount > 1 && !tracker.isModifier()) {
            mKeyPressTimingHandler.cancelKeyRepeatTimer();
        }
        // Up event will pass through.
    }

    if (action == MotionEvent.ACTION_MOVE) {
        for (int i = 0; i < pointerCount; i++) {
            PointerTracker tracker = getPointerTracker(nativeMotionEvent.getPointerId(i));
            tracker.onMoveEvent((int) nativeMotionEvent.getX(i), (int) nativeMotionEvent.getY(i));
        }
    } else {
        PointerTracker tracker = getPointerTracker(id);
        sendOnXEvent(action, eventTime, x, y, tracker);
    }

    return true;
}

From source file:com.harry.refresh.SwipyRefreshLayout.java

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mDirection == SwipeRefreshLayoutDirection.NONE) {
            return false;
        }/*from ww  w . ja  v a  2 s  .c  o m*/
        ensureTarget();

        final int action = MotionEventCompat.getActionMasked(ev);

        if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
            mReturningToStart = false;
        }

        switch (mDirection) {
        case BOTTOM:
            if (!isEnabled() || mReturningToStart || (!mBothDirection && canChildScrollDown()) || mRefreshing) {
                // Fail fast if we're not in a state where a swipe is possible
                return false;
            }
            break;
        case TOP:
        default:
            if (!isEnabled() || mReturningToStart || (!mBothDirection && canChildScrollUp()) || mRefreshing) {
                // Fail fast if we're not in a state where a swipe is possible
                return false;
            }
            break;
        }

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop(), true);
            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
            mIsBeingDragged = false;
            final float initialDownY = getMotionEventY(ev, mActivePointerId);
            if (initialDownY == -1) {
                return false;
            }
            mInitialDownY = initialDownY;

        case MotionEvent.ACTION_MOVE:
            if (mActivePointerId == INVALID_POINTER) {
                return false;
            }

            final float y = getMotionEventY(ev, mActivePointerId);
            if (y == -1) {
                return false;
            }
            if (mBothDirection) {
                if (y > mInitialDownY) {
                    setRawDirection(SwipeRefreshLayoutDirection.TOP);
                } else if (y < mInitialDownY) {
                    setRawDirection(SwipeRefreshLayoutDirection.BOTTOM);
                }
                if ((mDirection == SwipeRefreshLayoutDirection.BOTTOM && canChildScrollDown())
                        || (mDirection == SwipeRefreshLayoutDirection.TOP && canChildScrollUp())) {
                    mInitialDownY = y;
                    return false;
                }
            }
            float yDiff;
            switch (mDirection) {
            case BOTTOM:
                yDiff = mInitialDownY - y;
                break;
            case TOP:
            default:
                yDiff = y - mInitialDownY;
                break;
            }
            if (yDiff > mTouchSlop && !mIsBeingDragged) {
                switch (mDirection) {
                case BOTTOM:
                    mInitialMotionY = mInitialDownY - mTouchSlop;
                    break;
                case TOP:
                default:
                    mInitialMotionY = mInitialDownY + mTouchSlop;
                    break;
                }
                mIsBeingDragged = true;
                mProgress.setAlpha(STARTING_PROGRESS_ALPHA);
            }
            break;

        case MotionEventCompat.ACTION_POINTER_UP:
            onSecondaryPointerUp(ev);
            break;

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            mIsBeingDragged = false;
            mActivePointerId = INVALID_POINTER;
            break;
        }

        return mIsBeingDragged;
    }

From source file:android.support.v7.widget.RecyclerViewEx.java

@Override
public boolean onTouchEvent(MotionEvent e) {
    if (dispatchOnItemTouch(e)) {
        cancelTouch();/*from  ww w. j  a va 2 s  .co  m*/
        return true;
    }

    final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
    final boolean canScrollVertically = mLayout.canScrollVertically();

    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(e);

    final int action = MotionEventCompat.getActionMasked(e);
    final int actionIndex = MotionEventCompat.getActionIndex(e);

    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        mScrollPointerId = MotionEventCompat.getPointerId(e, 0);
        mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f);
        mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);
    }
        break;

    case MotionEventCompat.ACTION_POINTER_DOWN: {
        mScrollPointerId = MotionEventCompat.getPointerId(e, actionIndex);
        mInitialTouchX = mLastTouchX = (int) (MotionEventCompat.getX(e, actionIndex) + 0.5f);
        mInitialTouchY = mLastTouchY = (int) (MotionEventCompat.getY(e, actionIndex) + 0.5f);
    }
        break;

    case MotionEvent.ACTION_MOVE: {
        final int index = MotionEventCompat.findPointerIndex(e, mScrollPointerId);
        if (index < 0) {
            Log.e(TAG, "Error processing scroll; pointer index for id " + mScrollPointerId
                    + " not found. Did any MotionEvents get skipped?");
            return false;
        }

        final int x = (int) (MotionEventCompat.getX(e, index) + 0.5f);
        final int y = (int) (MotionEventCompat.getY(e, index) + 0.5f);
        if (mScrollState != SCROLL_STATE_DRAGGING) {
            final int dx = x - mInitialTouchX;
            final int dy = y - mInitialTouchY;
            boolean startScroll = false;
            if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) {
                mLastTouchX = mInitialTouchX + mTouchSlop * (dx < 0 ? -1 : 1);
                startScroll = true;
            }
            if (canScrollVertically && Math.abs(dy) > mTouchSlop) {
                mLastTouchY = mInitialTouchY + mTouchSlop * (dy < 0 ? -1 : 1);
                startScroll = true;
            }
            if (startScroll) {
                getParent().requestDisallowInterceptTouchEvent(true);
                setScrollState(SCROLL_STATE_DRAGGING);
            }
        }
        if (mScrollState == SCROLL_STATE_DRAGGING) {
            final int dx = x - mLastTouchX;
            final int dy = y - mLastTouchY;
            scrollByInternal(canScrollHorizontally ? -dx : 0, canScrollVertically ? -dy : 0);
        }
        mLastTouchX = x;
        mLastTouchY = y;
    }
        break;

    case MotionEventCompat.ACTION_POINTER_UP: {
        onPointerUp(e);
    }
        break;

    case MotionEvent.ACTION_UP: {
        mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
        final float xvel = canScrollHorizontally
                ? -VelocityTrackerCompat.getXVelocity(mVelocityTracker, mScrollPointerId)
                : 0;
        final float yvel = canScrollVertically
                ? -VelocityTrackerCompat.getYVelocity(mVelocityTracker, mScrollPointerId)
                : 0;
        if (!((xvel != 0 || yvel != 0) && fling((int) (xvel), (int) (yvel)))) {
            adjustPosition(mLastTouchX - mInitialTouchX);
        }
        mVelocityTracker.clear();
        releaseGlows();
    }
        break;

    case MotionEvent.ACTION_CANCEL: {
        cancelTouch();
    }
        break;
    }

    return true;
}