public void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) {
    if (!always && mCurItem == item) {
      setScrollingCacheEnabled(false);
      return;
    }

    item = mViewBehind.getMenuPage(item);

    final boolean dispatchSelected = mCurItem != item;
    mCurItem = item;

    if (mViewBehind.getbMode()) {
      final int destY = getDestScrollX(mCurItem);
      if (dispatchSelected && mOnPageChangeListener != null) {
        mOnPageChangeListener.onPageSelected(item);
      }
      if (dispatchSelected && mInternalPageChangeListener != null) {
        mInternalPageChangeListener.onPageSelected(item);
      }
      if (smoothScroll) {
        smoothScrollTo(0, destY, velocity);
      } else {
        completeScroll();
        scrollTo(0, destY);
      }
    } else {
      final int destX = getDestScrollX(mCurItem);
      if (dispatchSelected && mOnPageChangeListener != null) {
        mOnPageChangeListener.onPageSelected(item);
      }
      if (dispatchSelected && mInternalPageChangeListener != null) {
        mInternalPageChangeListener.onPageSelected(item);
      }
      if (smoothScroll) {
        smoothScrollTo(destX, 0, velocity);
      } else {
        completeScroll();
        scrollTo(destX, 0);
      }
    }
  }
 private void determineDrag(MotionEvent ev) {
   final int activePointerId = mActivePointerId;
   final int pointerIndex = getPointerIndex(ev, activePointerId);
   if (activePointerId == INVALID_POINTER || pointerIndex == INVALID_POINTER) return;
   final float x = MotionEventCompat.getX(ev, pointerIndex);
   final float dx = x - mLastMotionX;
   final float xDiff = Math.abs(dx);
   final float y = MotionEventCompat.getY(ev, pointerIndex);
   final float dy = y - mLastMotionY;
   final float yDiff = Math.abs(dy);
   if (mViewBehind.getbMode()) {
     if (yDiff > (isMenuOpen() ? mTouchSlop / 2 : mTouchSlop)
         && yDiff > xDiff
         && thisSlideAllowed(dy)) {
       startDrag();
       mLastMotionX = x;
       mLastMotionY = y;
       setScrollingCacheEnabled(true);
       // TODO add back in touch slop check
     } else if (yDiff > mTouchSlop) {
       mIsUnableToDrag = true;
     }
   } else {
     if (xDiff > (isMenuOpen() ? mTouchSlop / 2 : mTouchSlop)
         && xDiff > yDiff
         && thisSlideAllowed(dx)) {
       startDrag();
       mLastMotionX = x;
       mLastMotionY = y;
       setScrollingCacheEnabled(true);
       // TODO add back in touch slop check
     } else if (xDiff > mTouchSlop) {
       mIsUnableToDrag = true;
     }
   }
 }
  @Override
  public boolean onTouchEvent(MotionEvent ev) {

    if (!mEnabled) return false;

    if (!mIsBeingDragged && !thisTouchAllowed(ev)) return false;

    //		if (!mIsBeingDragged && !mQuickReturn)
    //			return false;

    final int action = ev.getAction();

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

    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
        int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = MotionEventCompat.getPointerId(ev, index);
        if (mViewBehind.getbMode()) {
          mLastMotionX = mInitialMotionX = ev.getY();
        } else {
          mLastMotionX = mInitialMotionX = ev.getX();
        }
        break;
      case MotionEvent.ACTION_MOVE:
        if (!mIsBeingDragged) {
          determineDrag(ev);
          if (mIsUnableToDrag) return false;
        }
        if (mIsBeingDragged) {
          // Scroll to follow the motion event
          final int activePointerIndex = getPointerIndex(ev, mActivePointerId);
          if (mActivePointerId == INVALID_POINTER) break;
          if (mViewBehind.getbMode()) {
            final float y = MotionEventCompat.getY(ev, activePointerIndex);
            final float deltaY = mLastMotionY - y;
            mLastMotionY = y;
            float oldScrollY = getScrollY();
            float scrollY = oldScrollY + deltaY;
            final float leftBound = getLeftBound();
            final float rightBound = getRightBound();
            if (scrollY < leftBound) {
              scrollY = leftBound;
            } else if (scrollY > rightBound) {
              scrollY = rightBound;
            }
            // Don't lose the rounded component
            mLastMotionY += scrollY - (int) scrollY;
            scrollTo(getScrollX(), (int) scrollY);
            pageScrolled((int) scrollY);
          } else {
            final float x = MotionEventCompat.getX(ev, activePointerIndex);
            final float deltaX = mLastMotionX - x;
            mLastMotionX = x;
            float oldScrollX = getScrollX();
            float scrollX = oldScrollX + deltaX;
            final float leftBound = getLeftBound();
            final float rightBound = getRightBound();
            if (scrollX < leftBound) {
              scrollX = leftBound;
            } else if (scrollX > rightBound) {
              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);
          if (mViewBehind.getbMode()) {
            int initialVelocity =
                (int) VelocityTrackerCompat.getYVelocity(velocityTracker, mActivePointerId);
            final int scrollY = getScrollY();
            final float pageOffset =
                (float) (scrollY - getDestScrollX(mCurItem)) / getBehindWidth();
            final int activePointerIndex = getPointerIndex(ev, mActivePointerId);
            if (mActivePointerId != INVALID_POINTER) {
              final float y = MotionEventCompat.getY(ev, activePointerIndex);
              final int totalDelta = (int) (y - mInitialMotionX);
              int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta);
              setCurrentItemInternal(nextPage, true, true, initialVelocity);
            } else {
              setCurrentItemInternal(mCurItem, true, true, initialVelocity);
            }
          } else {
            int initialVelocity =
                (int) VelocityTrackerCompat.getXVelocity(velocityTracker, mActivePointerId);
            final int scrollX = getScrollX();
            final float pageOffset =
                (float) (scrollX - getDestScrollX(mCurItem)) / getBehindWidth();
            final int activePointerIndex = getPointerIndex(ev, mActivePointerId);
            if (mActivePointerId != INVALID_POINTER) {
              final float x = MotionEventCompat.getX(ev, activePointerIndex);
              final int totalDelta = (int) (x - mInitialMotionX);
              int nextPage = determineTargetPage(pageOffset, initialVelocity, totalDelta);
              setCurrentItemInternal(nextPage, true, true, initialVelocity);
            } else {
              setCurrentItemInternal(mCurItem, true, true, initialVelocity);
            }
          }

          mActivePointerId = INVALID_POINTER;
          endDrag();
        } else if (mQuickReturn
            && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {
          // close the menu
          setCurrentItem(1);
          endDrag();
        }
        break;
      case MotionEvent.ACTION_CANCEL:
        if (mIsBeingDragged) {
          setCurrentItemInternal(mCurItem, true, true);
          mActivePointerId = INVALID_POINTER;
          endDrag();
        }
        break;
      case MotionEventCompat.ACTION_POINTER_DOWN:
        {
          final int indexx = MotionEventCompat.getActionIndex(ev);
          if (mViewBehind.getbMode()) {
            mLastMotionY = MotionEventCompat.getY(ev, indexx);
          } else {
            mLastMotionX = MotionEventCompat.getX(ev, indexx);
          }

          mActivePointerId = MotionEventCompat.getPointerId(ev, indexx);
          break;
        }
      case MotionEventCompat.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        int pointerIndex = getPointerIndex(ev, mActivePointerId);
        if (mActivePointerId == INVALID_POINTER) break;
        if (mViewBehind.getbMode()) {
          mLastMotionY = MotionEventCompat.getY(ev, pointerIndex);
        } else {
          mLastMotionX = MotionEventCompat.getX(ev, pointerIndex);
        }

        break;
    }
    return true;
  }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {

    if (!mEnabled) return false;

    final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;

    if (DEBUG) if (action == MotionEvent.ACTION_DOWN) Log.v(TAG, "Received ACTION_DOWN");

    if (action == MotionEvent.ACTION_CANCEL
        || action == MotionEvent.ACTION_UP
        || (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) {
      endDrag();
      return false;
    }

    switch (action) {
      case MotionEvent.ACTION_MOVE:
        determineDrag(ev);
        break;
      case MotionEvent.ACTION_DOWN:
        int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = MotionEventCompat.getPointerId(ev, index);
        if (mActivePointerId == INVALID_POINTER) break;
        if (mViewBehind.getbMode()) {
          mLastMotionY = mInitialMotionX = MotionEventCompat.getY(ev, index);
          mLastMotionX = MotionEventCompat.getX(ev, index);
          if (thisTouchAllowed(ev)) {
            mIsBeingDragged = false;
            mIsUnableToDrag = false;
            if (isMenuOpen()
                && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getY() + mScrollX)) {
              mQuickReturn = true;
            }
          } else {
            mIsUnableToDrag = true;
          }
        } else {
          mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, index);
          mLastMotionY = MotionEventCompat.getY(ev, index);
          if (thisTouchAllowed(ev)) {
            mIsBeingDragged = false;
            mIsUnableToDrag = false;
            if (isMenuOpen()
                && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {
              mQuickReturn = true;
            }
          } else {
            mIsUnableToDrag = true;
          }
        }

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

    if (!mIsBeingDragged) {
      if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
      }
      mVelocityTracker.addMovement(ev);
    }
    return mIsBeingDragged || mQuickReturn;
  }