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);
      }
    }
  }
 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
   super.onSizeChanged(w, h, oldw, oldh);
   // Make sure scroll position is set correctly.
   if (w != oldw) {
     // [ChrisJ] - This fixes the onConfiguration change for orientation issue..
     // maybe worth having a look why the recomputeScroll pos is screwing
     // up?
     completeScroll();
     scrollTo(getDestScrollX(mCurItem), getScrollY());
   }
 }
  /**
   * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
   *
   * @param x the number of pixels to scroll by on the X axis
   * @param y the number of pixels to scroll by on the Y axis
   * @param velocity the velocity associated with a fling, if applicable. (0 otherwise)
   */
  void smoothScrollTo(int x, int y, int velocity) {
    if (getChildCount() == 0) {
      // Nothing to do.
      setScrollingCacheEnabled(false);
      return;
    }
    int sx = getScrollX();
    int sy = getScrollY();
    int dx = x - sx;
    int dy = y - sy;
    if (dx == 0 && dy == 0) {
      completeScroll();
      if (isMenuOpen()) {
        if (mOpenedListener != null) mOpenedListener.onOpened();
      } else {
        if (mClosedListener != null) mClosedListener.onClosed();
      }
      return;
    }

    setScrollingCacheEnabled(true);
    mScrolling = true;

    final int width = getBehindWidth();
    final int halfWidth = width / 2;
    final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width);
    final float distance = halfWidth + halfWidth * distanceInfluenceForSnapDuration(distanceRatio);

    int duration = 0;
    velocity = Math.abs(velocity);
    if (velocity > 0) {
      duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
    } else {
      final float pageDelta = (float) Math.abs(dx) / width;
      duration = (int) ((pageDelta + 1) * 100);
      duration = MAX_SETTLE_DURATION;
    }
    duration = Math.min(duration, MAX_SETTLE_DURATION);

    mScroller.startScroll(sx, sy, dx, dy, duration);
    invalidate();
  }
  @Override
  public void computeScroll() {
    if (!mScroller.isFinished()) {
      if (mScroller.computeScrollOffset()) {
        int oldX = getScrollX();
        int oldY = getScrollY();
        int x = mScroller.getCurrX();
        int y = mScroller.getCurrY();

        if (oldX != x || oldY != y) {
          scrollTo(x, y);
          pageScrolled(x);
        }

        // Keep on drawing until the animation has finished.
        invalidate();
        return;
      }
    }

    // Done with scroll, clean up state.
    completeScroll();
  }
  @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);
        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;
          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);
          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);
          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;
        mLastMotionX = MotionEventCompat.getX(ev, pointerIndex);
        break;
    }
    return true;
  }