// Returns the distance that over the scroll limit.
 public int startScroll(int distance, int min, int max) {
   int currPosition = mScroller.getCurrX();
   int finalPosition = mScroller.isFinished() ? currPosition : mScroller.getFinalX();
   int newPosition = Utils.clamp(finalPosition + distance, min, max);
   if (newPosition != currPosition) {
     mScroller.startScroll(currPosition, 0, newPosition - currPosition, 0, 0);
   }
   return finalPosition + distance - newPosition;
 }
  public void fling(int velocityX) {
    if (getChildCount() > 0) {
      int width = getWidth() - getPaddingRight() - getPaddingLeft();
      int right = getChildAt(0).getWidth();

      if (DEBUG) {
        Log.d(TAG, "fling -> velocityX = " + velocityX);
        Log.d(TAG, "fling -> getScrollX() = " + getScrollX());
      }
      mScroller.fling(
          getScrollX(),
          getScrollY(),
          velocityX,
          0,
          0,
          Math.max(0, right - width),
          0,
          0,
          width / 2,
          0);

      int finalX = mScroller.getFinalX();
      int overX = 0;
      if (finalX <= 0 || finalX >= scrollPositionOfMostRecent()) {
        overX = width / 2;
      }

      finalX = getScrollXFromFinalX(finalX);
      if (DEBUG) {
        Log.d(TAG, "fling -> finalX = " + finalX);
      }
      mScroller.startScroll(
          getScrollX(), getScrollY(), finalX - getScrollX(), 0, getScrollTime(finalX));
      final boolean movingRight = velocityX > 0;

      postInvalidateOnAnimation();
    }
  }