Example usage for android.view ViewParent requestDisallowInterceptTouchEvent

List of usage examples for android.view ViewParent requestDisallowInterceptTouchEvent

Introduction

In this page you can find the example usage for android.view ViewParent requestDisallowInterceptTouchEvent.

Prototype

public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);

Source Link

Document

Called when a child does not want this parent and its ancestors to intercept touch events with ViewGroup#onInterceptTouchEvent(MotionEvent) .

Usage

From source file:com.lovebridge.library.view.staggeredGridView.ExtendableListView.java

private void scrollIfNeeded(final int y) {
    if (DBG)/*from   w w  w.ja  v a  2s .  c o m*/
        Log.d(TAG, "scrollIfNeeded y: " + y);
    final int rawDeltaY = y - mMotionY;
    final int deltaY = rawDeltaY - mMotionCorrection;
    int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
    if (mTouchMode == TOUCH_MODE_SCROLLING) {
        if (DBG)
            Log.d(TAG, "scrollIfNeeded TOUCH_MODE_SCROLLING");
        if (y != mLastY) {
            // stop our parent
            if (Math.abs(rawDeltaY) > mTouchSlop) {
                final ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
            final int motionIndex;
            if (mMotionPosition >= 0) {
                motionIndex = mMotionPosition - mFirstPosition;
            } else {
                // If we don't have a motion position that we can reliably
                // track,
                // pick something in the middle to make a best guess at
                // things below.
                motionIndex = getChildCount() / 2;
            }
            // No need to do all this work if we're not going to move anyway
            boolean atEdge = false;
            if (incrementalDeltaY != 0) {
                atEdge = moveTheChildren(deltaY, incrementalDeltaY);
            }
            // Check to see if we have bumped into the scroll limit
            View motionView = this.getChildAt(motionIndex);
            if (motionView != null) {
                if (atEdge) {
                    // TODO : edge effect & overscroll
                }
                mMotionY = y;
            }
            mLastY = y;
        }
    }
    // TODO : ELSE SUPPORT OVERSCROLL!
}

From source file:com.eland.android.eoas.Views.staggeredgridview.ExtendableListView.java

private void scrollIfNeeded(final int y) {
    if (DBG)/*from   www .j ava  2 s. c  om*/
        Log.d(TAG, "scrollIfNeeded y: " + y);
    final int rawDeltaY = y - mMotionY;
    final int deltaY = rawDeltaY - mMotionCorrection;
    int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;

    if (mTouchMode == TOUCH_MODE_SCROLLING) {
        if (DBG)
            Log.d(TAG, "scrollIfNeeded TOUCH_MODE_SCROLLING");
        if (y != mLastY) {
            // stop our parent
            if (Math.abs(rawDeltaY) > mTouchSlop) {
                final ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }

            final int motionIndex;
            if (mMotionPosition >= 0) {
                motionIndex = mMotionPosition - mFirstPosition;
            } else {
                // If we don't have a motion position that we can reliably track,
                // pick something in the middle to make a best guess at things below.
                motionIndex = getChildCount() / 2;
            }

            // No need to do all this work if we're not going to move anyway
            boolean atEdge = false;
            if (incrementalDeltaY != 0) {
                atEdge = moveTheChildren(deltaY, incrementalDeltaY);
            }

            // Check to see if we have bumped into the scroll limit
            View motionView = this.getChildAt(motionIndex);
            if (motionView != null) {
                // Check if the top of the motion view is where it is
                // supposed to be
                if (atEdge) {
                    mTouchMode = TOUCH_MODE_DONE_WAITING;
                }

                mMotionY = y;
            }
            mLastY = y;
        }

    }
    // TODO : ELSE SUPPORT OVERSCROLL!
}

From source file:com.buka.view.grid.ExtendableListView.java

/**
 * Starts a scroll that moves the difference between y and our last motions y
 * if it's a movement that represents a big enough scroll.
 *//*  w ww  .  j  ava2s  .c  o m*/
private boolean startScrollIfNeeded(final int y) {
    final int deltaY = y - mMotionY;
    final int distance = Math.abs(deltaY);
    // TODO : Overscroll?
    // final boolean overscroll = mScrollY != 0;
    final boolean overscroll = false;
    if (overscroll || distance > mTouchSlop) {
        if (overscroll) {
            mMotionCorrection = 0;
        } else {
            mTouchMode = TOUCH_MODE_SCROLLING;
            mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
        }

        // TODO : LONG PRESS
        setPressed(false);
        View motionView = getChildAt(mMotionPosition - mFirstPosition);
        if (motionView != null) {
            motionView.setPressed(false);
        }
        final ViewParent parent = getParent();
        if (parent != null) {
            parent.requestDisallowInterceptTouchEvent(true);
        }

        scrollIfNeeded(y);
        return true;
    }
    return false;
}

From source file:com.sgj.verticalviewpager.VerticalViewPager.java

/*********************************************************************************************/

private void requestParentDisallowInterceptTouchEvent(boolean paramBoolean) {
    ViewParent localViewParent = getParent();
    if (localViewParent == null)
        return;//from ww  w .ja  v  a 2  s  .  c om
    localViewParent.requestDisallowInterceptTouchEvent(paramBoolean);
}

From source file:caesar.feng.framework.widget.StaggeredGrid.ExtendableListView.java

/**
 * Starts a scroll that moves the difference between y and our last motions y
 * if it's a movement that represents a big enough scroll.
 *///ww w  .  j  a v a2 s .  c  o  m
private boolean startScrollIfNeeded(final int y) {
    final int deltaY = y - mMotionY;
    final int distance = Math.abs(deltaY);
    // TODO : Overscroll?
    // final boolean overscroll = mScrollY != 0;
    final boolean overscroll = false;
    if (overscroll || distance > mTouchSlop) {
        if (overscroll) {
            mMotionCorrection = 0;
        } else {
            mTouchMode = TOUCH_MODE_SCROLLING;
            mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
        }

        final Handler handler = getHandler();
        if (handler != null) {
            handler.removeCallbacks(mPendingCheckForLongPress);
        }
        setPressed(false);
        View motionView = getChildAt(mMotionPosition - mFirstPosition);
        if (motionView != null) {
            motionView.setPressed(false);
        }
        final ViewParent parent = getParent();
        if (parent != null) {
            parent.requestDisallowInterceptTouchEvent(true);
        }

        scrollIfNeeded(y);
        return true;
    }
    return false;
}

From source file:caesar.feng.framework.widget.StaggeredGrid.ExtendableListView.java

private void scrollIfNeeded(final int y) {
    if (DBG)/*www.  j  ava 2 s. c  o m*/
        Log.d(TAG, "scrollIfNeeded y: " + y);
    final int rawDeltaY = y - mMotionY;
    final int deltaY = rawDeltaY - mMotionCorrection;
    int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;

    if (mTouchMode == TOUCH_MODE_SCROLLING) {
        if (DBG)
            Log.d(TAG, "scrollIfNeeded TOUCH_MODE_SCROLLING");
        if (y != mLastY) {
            // stop our parent
            if (Math.abs(rawDeltaY) > mTouchSlop) {
                final ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }

            final int motionIndex;
            if (mMotionPosition >= 0) {
                motionIndex = mMotionPosition - mFirstPosition;
            } else {
                // If we don't have a motion position that we can reliably track,
                // pick something in the middle to make a best guess at things below.
                motionIndex = getChildCount() / 2;
            }

            // No need to do all this work if we're not going to move anyway
            boolean atEdge = false;
            if (incrementalDeltaY != 0) {
                atEdge = moveTheChildren(deltaY, incrementalDeltaY);
            }

            // Check to see if we have bumped into the scroll limit
            View motionView = this.getChildAt(motionIndex);
            if (motionView != null) {
                if (atEdge) {
                    // TODO : edge effect & overscroll
                }
                mMotionY = y;
            }
            mLastY = y;
        }

    }
    // TODO : ELSE SUPPORT OVERSCROLL!
}

From source file:com.isapp.android.circularviewpager.CircularViewPager.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;
    }// ww w .j  a  va  2s  .c o  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: {
        mScroller.abortAnimation();
        mPopulatePending = false;
        populate();
        // Remember where the motion event started
        mLastMotionX = mInitialMotionX = ev.getX();
        mLastMotionY = mInitialMotionY = ev.getY();
        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!");
                mMostRecentItemChangeDirection = x > mLastMotionX ? ITEM_CHANGE_DIRECTION_LEFT
                        : ITEM_CHANGE_DIRECTION_RIGHT;
                mIsBeingDragged = true;
                requestParentDisallowInterceptTouchEvent(true);
                mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop
                        : mInitialMotionX - mTouchSlop;
                mLastMotionY = y;
                setScrollState(SCROLL_STATE_DRAGGING);
                setScrollingCacheEnabled(true);
                // Disallow Parent Intercept, just in case
                ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
        }
        // Not else! Note that mIsBeingDragged can be set above.
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
            final float x = MotionEventCompat.getX(ev, activePointerIndex);
            needsInvalidate |= performDrag(x);
        }
        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 width = getClientWidth();
            final int scrollX = getScrollX();
            final ItemInfo ii = infoForCurrentScrollPosition();
            final int currentPage = ii.position;
            final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;
            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) {
            scrollToItem(mCurItem, true, 0, false);
            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) {
        ViewCompat.postInvalidateOnAnimation(this);
    }
    return true;
}

From source file:com.lcr.widget.ExtendableListView.java

private void scrollIfNeeded(final int y) {
    if (DBG)//  w  ww  .j a va  2s.c  o  m
        Log.i(TAG, "scrollIfNeeded y: " + y);
    final int rawDeltaY = y - mMotionY;
    final int deltaY = rawDeltaY - mMotionCorrection;
    int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;

    if (mTouchMode == TOUCH_MODE_SCROLLING) {
        if (DBG)
            Log.i(TAG, "scrollIfNeeded TOUCH_MODE_SCROLLING");
        if (y != mLastY) {
            // stop our parent
            if (Math.abs(rawDeltaY) > mTouchSlop) {
                final ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }

            final int motionIndex;
            if (mMotionPosition >= 0) {
                motionIndex = mMotionPosition - mFirstPosition;
            } else {
                // If we don't have a motion position that we can reliably track,
                // pick something in the middle to make a best guess at things below.
                motionIndex = getChildCount() / 2;
            }

            // No need to do all this work if we're not going to move anyway
            boolean atEdge = false;
            if (incrementalDeltaY != 0) {
                atEdge = moveTheChildren(deltaY, incrementalDeltaY);
            }

            // Check to see if we have bumped into the scroll limit
            View motionView = this.getChildAt(motionIndex);
            if (motionView != null) {
                if (atEdge) {
                    // TODO : edge effect & overscroll
                }
                mMotionY = y;
            }
            mLastY = y;
        }

    }
    // TODO : ELSE SUPPORT OVERSCROLL!
}

From source file:com.android.internal.widget.ViewPager.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 www  .  j a  v  a 2s . com

    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 & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        mScroller.abortAnimation();
        mPopulatePending = false;
        populate();

        // Remember where the motion event started
        mLastMotionX = mInitialMotionX = ev.getX();
        mLastMotionY = mInitialMotionY = ev.getY();
        mActivePointerId = ev.getPointerId(0);
        break;
    }
    case MotionEvent.ACTION_MOVE:
        if (!mIsBeingDragged) {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float xDiff = Math.abs(x - mLastMotionX);
            final float y = ev.getY(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;
                requestParentDisallowInterceptTouchEvent(true);
                mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop
                        : mInitialMotionX - mTouchSlop;
                mLastMotionY = y;
                setScrollState(SCROLL_STATE_DRAGGING);
                setScrollingCacheEnabled(true);

                // Disallow Parent Intercept, just in case
                ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
        }
        // Not else! Note that mIsBeingDragged can be set above.
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(activePointerIndex);
            needsInvalidate |= performDrag(x);
        }
        break;
    case MotionEvent.ACTION_UP:
        if (mIsBeingDragged) {
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);

            mPopulatePending = true;

            final float scrollStart = getScrollStart();
            final float scrolledPages = scrollStart / getPaddedWidth();
            final ItemInfo ii = infoForFirstVisiblePage();
            final int currentPage = ii.position;
            final float nextPageOffset;
            if (isLayoutRtl()) {
                nextPageOffset = (ii.offset - scrolledPages) / ii.widthFactor;
            } else {
                nextPageOffset = (scrolledPages - ii.offset) / ii.widthFactor;
            }

            final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(activePointerIndex);
            final int totalDelta = (int) (x - mInitialMotionX);
            final int nextPage = determineTargetPage(currentPage, nextPageOffset, initialVelocity, totalDelta);
            setCurrentItemInternal(nextPage, true, true, initialVelocity);

            mActivePointerId = INVALID_POINTER;
            endDrag();
            mLeftEdge.onRelease();
            mRightEdge.onRelease();
            needsInvalidate = true;
        }
        break;
    case MotionEvent.ACTION_CANCEL:
        if (mIsBeingDragged) {
            scrollToItem(mCurItem, true, 0, false);
            mActivePointerId = INVALID_POINTER;
            endDrag();
            mLeftEdge.onRelease();
            mRightEdge.onRelease();
            needsInvalidate = true;
        }
        break;
    case MotionEvent.ACTION_POINTER_DOWN: {
        final int index = ev.getActionIndex();
        final float x = ev.getX(index);
        mLastMotionX = x;
        mActivePointerId = ev.getPointerId(index);
        break;
    }
    case MotionEvent.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
        break;
    }
    if (needsInvalidate) {
        postInvalidateOnAnimation();
    }
    return true;
}

From source file:com.pix.weibohomedemo.widget.ViewPagerModify.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 www  . j a  va2 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: {
        mScroller.abortAnimation();
        mPopulatePending = false;
        populate();

        // Remember where the motion event started
        mLastMotionX = mInitialMotionX = ev.getX();
        mLastMotionY = mInitialMotionY = ev.getY();
        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 (xDiff > mTouchSlop && xDiff > yDiff) {
                mIsBeingDragged = true;
                requestParentDisallowInterceptTouchEvent(true);
                mLastMotionX = x - mInitialMotionX > 0 ? mInitialMotionX + mTouchSlop
                        : mInitialMotionX - mTouchSlop;
                mLastMotionY = y;
                setScrollState(SCROLL_STATE_DRAGGING);
                setScrollingCacheEnabled(true);

                // Disallow Parent Intercept, just in case
                ViewParent parent = getParent();
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
        }
        // Not else! Note that mIsBeingDragged can be set above.
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
            final float x = MotionEventCompat.getX(ev, activePointerIndex);
            needsInvalidate |= performDrag(x);
        }
        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 width = getClientWidth();
            final int scrollX = getScrollX();
            final ItemInfo ii = infoForCurrentScrollPosition();
            final int currentPage = ii.position;
            final float pageOffset = (((float) scrollX / width) - ii.offset) / ii.widthFactor;
            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) {
            scrollToItem(mCurItem, true, 0, false);
            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) {
        ViewCompat.postInvalidateOnAnimation(this);
    }
    return true;
}