Example usage for android.view VelocityTracker obtain

List of usage examples for android.view VelocityTracker obtain

Introduction

In this page you can find the example usage for android.view VelocityTracker obtain.

Prototype

static public VelocityTracker obtain() 

Source Link

Document

Retrieve a new VelocityTracker object to watch the velocity of a motion.

Usage

From source file:com.aretha.slidemenu.SlideMenu.java

public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // we want to draw drop shadow of content
    mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    mVelocityTracker = VelocityTracker.obtain();
    mScroller = new Scroller(context, mInterpolator);
    mContentHitRect = new Rect();
    STATUS_BAR_HEIGHT = (int) getStatusBarHeight(context);
    setWillNotDraw(false);/*from ww  w .ja va2  s.  c  om*/

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideMenu, defStyle, 0);

    // Set the shadow attributes
    setPrimaryShadowWidth(a.getDimension(R.styleable.SlideMenu_primaryShadowWidth, 30));
    setSecondaryShadowWidth(a.getDimension(R.styleable.SlideMenu_secondaryShadowWidth, 30));

    Drawable primaryShadowDrawable = a.getDrawable(R.styleable.SlideMenu_primaryShadowDrawable);
    if (null == primaryShadowDrawable) {
        primaryShadowDrawable = new GradientDrawable(Orientation.LEFT_RIGHT,
                new int[] { Color.TRANSPARENT, Color.argb(99, 0, 0, 0) });
    }
    setPrimaryShadowDrawable(primaryShadowDrawable);

    Drawable secondaryShadowDrawable = a.getDrawable(R.styleable.SlideMenu_primaryShadowDrawable);
    if (null == secondaryShadowDrawable) {
        secondaryShadowDrawable = new GradientDrawable(Orientation.LEFT_RIGHT,
                new int[] { Color.argb(99, 0, 0, 0), Color.TRANSPARENT });
    }
    setSecondaryShadowDrawable(secondaryShadowDrawable);

    mSlideDirectionFlag = a.getInt(R.styleable.SlideMenu_slideDirection,
            FLAG_DIRECTION_LEFT | FLAG_DIRECTION_RIGHT);
    setFocusable(true);
    setFocusableInTouchMode(true);
    a.recycle();
}

From source file:com.personal.taskmanager2.utilities.RecyclerViewTouchListener.java

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    boolean mPaused = mRecyclerView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE;

    mViewWidth = mRecyclerView.getWidth();

    switch (e.getActionMasked()) {
    case MotionEvent.ACTION_CANCEL: {
        if (mVelocityTracker == null) {
            break;
        }//from w w w. j ava  2s  .c  om
        Log.d(TAG, "Cancel Intercept");

        if (mChildView != null) {
            // cancel
            mChildView.animate().translationX(0).alpha(1).setDuration(mAnimationTime).setListener(null);
        }
        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mDownX = 0;
        mDeltaX = 0;
        mChildView = null;
        mChildPosition = RecyclerView.NO_POSITION;
        mSwiping = false;

        break;
    }

    case MotionEvent.ACTION_DOWN: {
        if (mPaused) {
            return false;
        }
        Log.d(TAG, "Down Intercept");

        mChildView = mRecyclerView.findChildViewUnder(e.getRawX(), e.getY());
        if (mChildView == null) {
            Log.d(TAG, "child view is null in action down");
            break;
        }

        mChildPosition = mRecyclerView.getChildPosition(mChildView);
        mDownX = e.getRawX();
        if (mCallbacks.canDismiss(mChildPosition)) {
            mVelocityTracker = VelocityTracker.obtain();
            mVelocityTracker.addMovement(e);
        } else {
            mChildView = null;
        }
        //rv.onTouchEvent(e);
        return false;
    }

    case MotionEvent.ACTION_UP: {
        if (mVelocityTracker == null) {
            break;
        }

        Log.d(TAG, "Up Intercept");

        float deltaX = e.getRawX() - mDownX;
        float absDeltaX = Math.abs(deltaX);
        mVelocityTracker.addMovement(e);
        mVelocityTracker.computeCurrentVelocity(1000);
        float velocityX = mVelocityTracker.getXVelocity();
        float absVelocityX = Math.abs(velocityX);
        float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
        boolean dismiss = false;
        boolean dismissRight = false;
        if (absDeltaX > mViewWidth / 2) {
            dismiss = true;
            dismissRight = deltaX > 0;
        } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
                && absVelocityY < absVelocityX) {
            // dismiss only if flinging in the same direction as dragging
            dismiss = (velocityX < 0) == (deltaX < 0);
            dismissRight = mVelocityTracker.getXVelocity() > 0;
        }

        if (dismiss) {
            dismiss(mChildView, mChildPosition, dismissRight);
        } else {
            mChildView.animate().alpha(1).translationX(0).setDuration(mAnimationTime).setListener(null);
        }

        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mDownX = 0;
        mDeltaX = 0;
        mChildView = null;
        mChildPosition = RecyclerView.NO_POSITION;
        mSwiping = false;
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        if (mVelocityTracker == null || mPaused) {
            break;
        }

        Log.d(TAG, "Move Intercept");

        mVelocityTracker.addMovement(e);
        float deltaX = e.getRawX() - mDownX;
        float absDeltaX = Math.abs(deltaX);
        if (absDeltaX > mSlop) {
            mDeltaX = deltaX;
            return true;
        }
        break;
    }
    }
    return false;
}

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

public ADrawerLayout(Context ctx, AttributeSet attrs, int defStyle) {
    super(ctx, attrs, defStyle);

    ViewConfiguration vc = ViewConfiguration.get(ctx);
    mTouchSlop = vc.getScaledTouchSlop();
    mVelocityTracker = VelocityTracker.obtain();

    // Read the attributes passed in the XML view declaration
    TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.ADrawerLayout);
    try {//ww  w . ja  va 2 s.c  om
        Rect innerMargins = new Rect();
        innerMargins.left = a.getDimensionPixelSize(R.styleable.ADrawerLayout_innerMarginLeft, 0);
        innerMargins.top = a.getDimensionPixelSize(R.styleable.ADrawerLayout_innerMarginTop, 0);
        innerMargins.right = a.getDimensionPixelSize(R.styleable.ADrawerLayout_innerMarginRight, 0);
        innerMargins.bottom = a.getDimensionPixelSize(R.styleable.ADrawerLayout_innerMarginBottom, 0);
        setInnerMargins(innerMargins);

        boolean innerIsGlobalLeft = a.getBoolean(R.styleable.ADrawerLayout_innerMarginIsGlobalLeft, false);
        boolean innerIsGlobalTop = a.getBoolean(R.styleable.ADrawerLayout_innerMarginIsGlobalTop, false);
        boolean innerIsGlobalRight = a.getBoolean(R.styleable.ADrawerLayout_innerMarginIsGlobalRight, false);
        boolean innerIsGlobalBottom = a.getBoolean(R.styleable.ADrawerLayout_innerMarginIsGlobalBottom, false);
        setInnerIsGlobal(innerIsGlobalLeft, innerIsGlobalTop, innerIsGlobalRight, innerIsGlobalBottom);

        Rect peekSize = new Rect();
        peekSize.left = a.getDimensionPixelSize(R.styleable.ADrawerLayout_peekSizeLeft, 0);
        peekSize.top = a.getDimensionPixelSize(R.styleable.ADrawerLayout_peekSizeTop, 0);
        peekSize.right = a.getDimensionPixelSize(R.styleable.ADrawerLayout_peekSizeRight, 0);
        peekSize.bottom = a.getDimensionPixelSize(R.styleable.ADrawerLayout_peekSizeBottom, 0);
        setPeekSize(peekSize);

        boolean restrictToPeekLeft = a.getBoolean(R.styleable.ADrawerLayout_restrictToPeekLeft, true);
        boolean restrictToPeekTop = a.getBoolean(R.styleable.ADrawerLayout_restrictToPeekTop, true);
        boolean restrictToPeekRight = a.getBoolean(R.styleable.ADrawerLayout_restrictToPeekRight, true);
        boolean restrictToPeekBottom = a.getBoolean(R.styleable.ADrawerLayout_restrictToPeekBottom, true);
        setRestrictTouchesToPeekArea(restrictToPeekLeft, restrictToPeekTop, restrictToPeekRight,
                restrictToPeekBottom);
    } finally {
        a.recycle();
    }
}

From source file:com.gitstudy.rili.liarbry.CalendarLayout.java

public CalendarLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    setOrientation(LinearLayout.VERTICAL);
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CalendarLayout);
    mContentViewId = array.getResourceId(R.styleable.CalendarLayout_calendar_content_view_id, 0);
    mDefaultStatus = array.getInt(R.styleable.CalendarLayout_default_status, STATUS_EXPAND);
    mCalendarShowMode = array.getInt(R.styleable.CalendarLayout_calendar_show_mode,
            CALENDAR_SHOW_MODE_BOTH_MONTH_WEEK_VIEW);
    mGestureMode = array.getInt(R.styleable.CalendarLayout_gesture_mode, GESTURE_MODE_DEFAULT);
    array.recycle();// w w w . ja  v a  2  s  .  c o  m
    mVelocityTracker = VelocityTracker.obtain();
    final ViewConfiguration configuration = ViewConfiguration.get(context);
    mTouchSlop = configuration.getScaledTouchSlop();
    mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
}

From source file:org.zywx.wbpalmstar.engine.EBounceView.java

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    int action = e.getAction();
    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }//from  w w w .  j  ava 2  s .  c o m
    mVelocityTracker.addMovement(e);
    if (!mBounce) {
        switch (action) {
        case MotionEvent.ACTION_UP:
            handlerTracker();
            break;
        }
        return false;
    }

    int y = (int) e.getRawY();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        mLastY = y;
        break;
    case MotionEvent.ACTION_MOVE:
        int m = y - mLastY;
        boolean can = (m >= 0 ? m : -m) > mTouchSlop;
        if (m > 0 && !mBottomLoading && can && !mTopAutoRefresh) {
            if (topCanBounce()) {
                mIsTop = true;
                if (mTopNotify) {
                    mBrwView.onBounceStateChange(EViewEntry.F_BOUNCE_TYPE_TOP, F_BOUNCEVIEW_STATE_PULL_RELOAD);
                }
                return true;
            }
        } else if (m < 0 && !mTopLoading && can) {
            if (bottomCanBounce()) {
                mIsBottom = true;
                if (mBottomNotify) {
                    mBrwView.onBounceStateChange(EViewEntry.F_BOUNCE_TYPE_BOTTOM,
                            F_BOUNCEVIEW_STATE_PULL_RELOAD);
                }
                return true;
            }
        }
        mLastY = y;
        break;
    case MotionEvent.ACTION_UP:
        handlerTracker();
        break;
    }
    return false;
}

From source file:com.nononsenseapps.feeder.ui.SwipeDismissTouchListener.java

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    // offset because the view is translated during swipe
    motionEvent.offsetLocation(mTranslationX, 0);

    if (mViewWidth < 2) {
        mViewWidth = mView.getWidth();/*from   ww  w  .java  2s .c  o  m*/
    }

    switch (motionEvent.getActionMasked()) {
    case MotionEvent.ACTION_DOWN: {
        // TODO: ensure this is a finger, and set a flag
        mDownX = motionEvent.getRawX();
        mDownY = motionEvent.getRawY();
        if (mCallbacks.canDismiss(mToken)) {
            mVelocityTracker = VelocityTracker.obtain();
            mVelocityTracker.addMovement(motionEvent);
        }
        return false;
    }

    case MotionEvent.ACTION_UP: {
        if (mVelocityTracker == null) {
            break;
        }

        float deltaX = motionEvent.getRawX() - mDownX;
        mVelocityTracker.addMovement(motionEvent);
        mVelocityTracker.computeCurrentVelocity(1000);
        float velocityX = mVelocityTracker.getXVelocity();
        float absVelocityX = Math.abs(velocityX);
        float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
        boolean dismiss = false;
        boolean dismissRight = false;
        if (Math.abs(deltaX) > mViewWidth / 2 && mSwiping) {
            dismiss = true;
            dismissRight = deltaX > 0;
        } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
                && absVelocityY < absVelocityX && absVelocityY < absVelocityX && mSwiping) {
            // dismiss only if flinging in the same direction as dragging
            dismiss = (velocityX < 0) == (deltaX < 0);
            dismissRight = mVelocityTracker.getXVelocity() > 0;
        }
        if (dismiss) {
            // dismiss
            mSwipingView.animate().translationX(dismissRight ? mViewWidth : -mViewWidth)
                    //.alpha(0)
                    .setDuration(mAnimationTime).setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            performDismiss();
                        }
                    });
        } else if (mSwiping) {
            // cancel
            mSwipingView.animate().translationX(0)
                    //.alpha(1)
                    .setDuration(mAnimationTime).setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            mCallbacks.onSwipeCancelled();
                        }
                    });
        }
        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mTranslationX = 0;
        mDownX = 0;
        mDownY = 0;
        mSwiping = false;
        notNotifiedSwipeStart = true;
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        if (mVelocityTracker == null) {
            break;
        }

        mSwipingView.animate().translationX(0)
                //.alpha(1)
                .setDuration(mAnimationTime).setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        mCallbacks.onSwipeCancelled();
                    }
                });
        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mTranslationX = 0;
        mDownX = 0;
        mDownY = 0;
        mSwiping = false;
        notNotifiedSwipeStart = true;
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        if (mVelocityTracker == null) {
            break;
        }

        mVelocityTracker.addMovement(motionEvent);
        float deltaX = motionEvent.getRawX() - mDownX;
        float deltaY = motionEvent.getRawY() - mDownY;
        if (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
            mSwiping = true;
            mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
            mView.getParent().requestDisallowInterceptTouchEvent(true);

            // Cancel listview's touch
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(MotionEvent.ACTION_CANCEL
                    | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
            mView.onTouchEvent(cancelEvent);
            cancelEvent.recycle();
        }

        if (mSwiping) {
            if (notNotifiedSwipeStart) {
                notNotifiedSwipeStart = false;
                mCallbacks.onSwipeStarted(deltaX > 0);
            }
            mTranslationX = deltaX;
            mSwipingView.setTranslationX(deltaX - mSwipingSlop);
            //mView.setAlpha(mInterpolator.getInterpolation(1f - 1f * Math.abs(deltaX) / mViewWidth));
            //                    mView.setAlpha(Math.max(0f, Math.min(1f,
            //                            1f - 2f * Math.abs(deltaX) / mViewWidth)));
            return true;
        }
        break;
    }
    }
    return false;
}

From source file:com.tasomaniac.openwith.resolver.ResolverDrawerLayout.java

public ResolverDrawerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ResolverDrawerLayout, defStyleAttr,
            0);/*from ww w . j  a va2 s  . co  m*/
    mMaxWidth = a.getDimensionPixelSize(R.styleable.ResolverDrawerLayout_resolverMaxWidth, -1);
    mMaxCollapsedHeight = a.getDimensionPixelSize(R.styleable.ResolverDrawerLayout_maxCollapsedHeight, 0);
    mMaxCollapsedHeightSmall = a.getDimensionPixelSize(R.styleable.ResolverDrawerLayout_maxCollapsedHeightSmall,
            mMaxCollapsedHeight);
    a.recycle();

    mParentHelper = new NestedScrollingParentHelper(this);

    //noinspection ResourceType
    mScroller = ScrollerCompat.create(context,
            AnimationUtils.loadInterpolator(context, android.R.interpolator.decelerate_quint));
    mVelocityTracker = VelocityTracker.obtain();

    final ViewConfiguration vc = ViewConfiguration.get(context);
    mTouchSlop = vc.getScaledTouchSlop();
    mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
}

From source file:com.github.shareme.gwsswwipetodismiss.library.SwipeDismissTouchListener.java

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    // offset because the view is translated during swipe
    motionEvent.offsetLocation(mTranslationX, 0);

    if (mViewWidth < 2) {
        mViewWidth = mView.getWidth();/*from  w  w  w  .  j a  v a  2  s.c om*/
    }

    switch (MotionEventCompat.getActionMasked(motionEvent)) {
    case MotionEvent.ACTION_DOWN: {
        // TODO: ensure this is a finger, and set a flag
        mDownX = motionEvent.getRawX();
        mDownY = motionEvent.getRawY();
        mVelocityTracker = VelocityTracker.obtain();
        mVelocityTracker.addMovement(motionEvent);
        view.onTouchEvent(motionEvent);
        return false;
    }

    case MotionEvent.ACTION_UP: {
        if (mVelocityTracker == null) {
            break;
        }

        float deltaX = motionEvent.getRawX() - mDownX;
        float deltaY = motionEvent.getRawY() - mDownY;
        mVelocityTracker.addMovement(motionEvent);
        mVelocityTracker.computeCurrentVelocity(1000);
        float velocityX = Math.abs(mVelocityTracker.getXVelocity());
        float velocityY = Math.abs(mVelocityTracker.getYVelocity());
        boolean dismiss = false;
        boolean dismissRight = false;
        if (Math.abs(deltaY) < Math.abs(deltaX)) {
            if (Math.abs(deltaX) > Math.round(mViewWidth * SWIPE_SENSITIVITY)) {
                dismiss = true;
                dismissRight = deltaX > 0;
            } else if (Math.abs(deltaX) > mSlop && mMinFlingVelocity <= velocityX
                    && velocityX <= mMaxFlingVelocity && velocityY < velocityX) {
                dismiss = true;
                dismissRight = mVelocityTracker.getXVelocity() > 0;
            }
        }
        if (dismiss) {
            // dismiss
            mView.animate().translationX(dismissRight ? mViewWidth : -mViewWidth).alpha(0)
                    .setDuration(mAnimationTime).setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            performDismiss();
                        }
                    });
        } else {
            // cancel
            mView.animate().translationX(0).alpha(1).setDuration(mAnimationTime).setListener(null);
        }
        mVelocityTracker = null;
        mTranslationX = 0;
        mDownX = 0;
        mDownY = 0;
        mSwiping = false;
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        if (mVelocityTracker == null) {
            break;
        }

        mVelocityTracker.addMovement(motionEvent);
        float deltaX = motionEvent.getRawX() - mDownX;
        if (Math.abs(deltaX) > mSlop) {
            mSwiping = true;
            mView.getParent().requestDisallowInterceptTouchEvent(true);

            // Cancel listview's touch
            MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
            cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (MotionEventCompat
                    .getActionIndex(motionEvent) << MotionEventCompat.ACTION_POINTER_INDEX_SHIFT));
            mView.onTouchEvent(cancelEvent);
        }

        if (mSwiping) {
            mTranslationX = deltaX;
            setTranslationX(mView, deltaX);
            // TODO: use an ease-out interpolator or such
            setAlpha(mView, Math.max(0f, Math.min(1f, 1f - Math.abs(deltaX) / SWIPE_SENSITIVITY * mViewWidth)));
            return true;
        }
        break;
    }
    }
    return false;
}

From source file:com.base.view.slidemenu.SlideMenu.java

public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // we want to draw drop shadow of content
    mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    mVelocityTracker = VelocityTracker.obtain();
    mContentHitRect = new Rect();
    mEdgeSlideDetectRect = new Rect();
    STATUS_BAR_HEIGHT = (int) getStatusBarHeight(context);
    setWillNotDraw(false);/*from   w  w  w.  ja  v a2s . c om*/

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideMenu, defStyle, 0);

    // Set the shadow attributes
    setPrimaryShadowWidth(a.getDimension(R.styleable.SlideMenu_primaryShadowWidth, 30));
    setSecondaryShadowWidth(a.getDimension(R.styleable.SlideMenu_secondaryShadowWidth, 30));

    Drawable primaryShadowDrawable = a.getDrawable(R.styleable.SlideMenu_primaryShadowDrawable);
    if (null == primaryShadowDrawable) {
        primaryShadowDrawable = new GradientDrawable(Orientation.LEFT_RIGHT,
                new int[] { Color.TRANSPARENT, Color.argb(99, 0, 0, 0) });
    }
    setPrimaryShadowDrawable(primaryShadowDrawable);

    Drawable secondaryShadowDrawable = a.getDrawable(R.styleable.SlideMenu_secondaryShadowDrawable);
    if (null == secondaryShadowDrawable) {
        secondaryShadowDrawable = new GradientDrawable(Orientation.LEFT_RIGHT,
                new int[] { Color.argb(99, 0, 0, 0), Color.TRANSPARENT });
    }
    setSecondaryShadowDrawable(secondaryShadowDrawable);

    int interpolatorResId = a.getResourceId(R.styleable.SlideMenu_interpolator, -1);
    setInterpolator(-1 == interpolatorResId ? DEFAULT_INTERPOLATOR
            : AnimationUtils.loadInterpolator(context, interpolatorResId));

    mSlideDirectionFlag = a.getInt(R.styleable.SlideMenu_slideDirection,
            FLAG_DIRECTION_LEFT | FLAG_DIRECTION_RIGHT);

    setEdgeSlideEnable(a.getBoolean(R.styleable.SlideMenu_edgeSlide, false));
    setEdgetSlideWidth(a.getDimensionPixelSize(R.styleable.SlideMenu_edgeSlideWidth, 100));
    a.recycle();

    setFocusable(true);
    setFocusableInTouchMode(true);
}

From source file:com.iangclifton.auid.horizontaliconview.HorizontalIconView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }//  www.ja v a2 s.c  o m
    mVelocityTracker.addMovement(ev);

    final int action = MotionEventCompat.getActionMasked(ev);
    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
        }

        // Remember where the motion event started
        mPreviousX = (int) MotionEventCompat.getX(ev, 0);
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
        if (activePointerIndex == INVALID_POINTER) {
            Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
            break;
        }

        final int x = (int) MotionEventCompat.getX(ev, 0);
        int deltaX = (int) (mPreviousX - x);
        if (!mIsBeingDragged && Math.abs(deltaX) > mTouchSlop) {
            mIsBeingDragged = true;
            if (deltaX > 0) {
                deltaX -= mTouchSlop;
            } else {
                deltaX += mTouchSlop;
            }
        }
        if (mIsBeingDragged) {
            // Scroll to follow the motion event
            mPreviousX = x;

            final int oldX = getScrollX();
            final int range = mScrollRange;

            if (overScrollBy(deltaX, 0, oldX, 0, range, 0, mOverscrollDistance, 0, true)) {
                // Break our velocity if we hit a scroll barrier.
                mVelocityTracker.clear();
            }

            if (mEdgeEffectLeft != null) {
                final int pulledToX = oldX + deltaX;
                if (pulledToX < 0) {
                    mEdgeEffectLeft.onPull((float) deltaX / getWidth());
                    if (!mEdgeEffectRight.isFinished()) {
                        mEdgeEffectRight.onRelease();
                    }
                } else if (pulledToX > range) {
                    mEdgeEffectRight.onPull((float) deltaX / getWidth());
                    if (!mEdgeEffectLeft.isFinished()) {
                        mEdgeEffectLeft.onRelease();
                    }
                }
                if (!mEdgeEffectLeft.isFinished() || !mEdgeEffectRight.isFinished()) {
                    postInvalidateOnAnimation();
                }

            }

        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        if (mIsBeingDragged) {
            mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            int initialVelocity = (int) mVelocityTracker.getXVelocity(mActivePointerId);

            if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                fling(-initialVelocity);
            } else {
                if (mScroller.springBack(getScrollX(), 0, 0, mScrollRange, 0, 0)) {
                    postInvalidateOnAnimation();
                }
            }

            mActivePointerId = INVALID_POINTER;
            mIsBeingDragged = false;
            mVelocityTracker.recycle();
            mVelocityTracker = null;

            if (mEdgeEffectLeft != null) {
                mEdgeEffectLeft.onRelease();
                mEdgeEffectRight.onRelease();
            }
        } else {
            // Was not being dragged, was this a press on an icon?
            final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
            if (activePointerIndex == INVALID_POINTER) {
                return false;
            }
            final int x = (int) ev.getX(activePointerIndex) + getScrollX();
            final int y = (int) ev.getY(activePointerIndex);
            int i = 0;
            for (Rect rect : mIconPositions) {
                if (rect.contains(x, y)) {
                    final int position = i + mSkippedIconCount;
                    Toast.makeText(getContext(),
                            "Pressed icon " + position + "; rect count: " + mIconPositions.size(),
                            Toast.LENGTH_SHORT).show();
                    break;
                }
                i++;
            }
        }
        break;
    }
    case MotionEvent.ACTION_CANCEL: {
        if (mIsBeingDragged) {
            if (mScroller.springBack(getScrollX(), 0, 0, mScrollRange, 0, 0)) {
                postInvalidateOnAnimation();
            }
            mActivePointerId = INVALID_POINTER;
            mIsBeingDragged = false;
            if (mVelocityTracker != null) {
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            }

            if (mEdgeEffectLeft != null) {
                mEdgeEffectLeft.onRelease();
                mEdgeEffectRight.onRelease();
            }
        }
        break;
    }
    case MotionEvent.ACTION_POINTER_UP: {
        onSecondaryPointerUp(ev);
        break;
    }
    }
    return true;
}