@Override
 public void applyTransformation(float interpolatedTime, Transformation t) {
   int targetTop = 0;
   int endTarget = (int) mSpinnerFinalOffset;
   targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
   int offset = targetTop - mTarget.getTop();
   setTargetOffsetTop(offset, false /* requires update */);
 }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {

    if (!isEnabled() || canChildScrollUp() || mRefreshing) {
      return false;
    }

    final int action = MotionEventCompat.getActionMasked(ev);

    switch (action) {
      case MotionEvent.ACTION_DOWN:
        setTargetOffsetTop(0, true);
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        mIsBeingDragged = false;
        final float initialMotionY = getMotionEventY(ev, mActivePointerId);
        if (initialMotionY == -1) {
          return false;
        }
        mInitialMotionY = initialMotionY;
        break;
      case MotionEvent.ACTION_MOVE:
        if (mActivePointerId == INVALID_POINTER) {
          return false;
        }
        final float y = getMotionEventY(ev, mActivePointerId);
        if (y == -1) {
          return false;
        }
        final float yDiff = y - mInitialMotionY;
        //                if (Math.abs(yDiff) > mTouchSlop && !mIsBeingDragged) {
        //                    mIsBeingDragged = true;
        //                    mMode = yDiff > 0 ? MODE_TOP : MODE_BOTTOM;
        //                }
        if (yDiff > mTouchSlop && !mIsBeingDragged) {
          mIsBeingDragged = true;
        }
        break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:
        mIsBeingDragged = false;
        mActivePointerId = INVALID_POINTER;
        break;
      case MotionEventCompat.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        break;
    }

    return mIsBeingDragged;
  }
 private void moveToStart(float interpolatedTime) {
   int targetTop = mFrom - (int) (mFrom * interpolatedTime);
   int offset = targetTop - mTarget.getTop();
   setTargetOffsetTop(offset, false);
 }
  @Override
  public boolean onTouchEvent(MotionEvent ev) {

    if (!mIsBeingDragged) {
      return super.onTouchEvent(ev);
    }

    final int action = MotionEventCompat.getActionMasked(ev);

    switch (action) {
      case MotionEvent.ACTION_MOVE:
        {
          final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
          if (pointerIndex < 0) {
            return false;
          }

          final float y = MotionEventCompat.getY(ev, pointerIndex);
          //                final float yDiff = Math.abs(y - mInitialMotionY);
          final float yDiff = y - mInitialMotionY;
          final float scrollTop = yDiff * DRAG_RATE;
          float originalDragPercent = scrollTop / mTotalDragDistance;
          if (originalDragPercent < 0) {
            return false;
          }
          float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
          //                float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;
          //                    float adjustedPercent = dragPercent;
          float extraOS = Math.abs(scrollTop) - mTotalDragDistance;
          float slingshotDist = mSpinnerFinalOffset;
          float tensionSlingshotPercent =
              Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist);
          float tensionPercent =
              (float) ((tensionSlingshotPercent / 4) - Math.pow((tensionSlingshotPercent / 4), 2))
                  * 2f;
          float extraMove = (slingshotDist) * tensionPercent * 2;
          int targetY = (int) ((slingshotDist * dragPercent) + extraMove);
          if (mRefreshView.getVisibility() != View.VISIBLE) {
            mRefreshView.setVisibility(View.VISIBLE);
          }
          if (scrollTop < mTotalDragDistance) {
            mRefreshDrawable.setPercent(dragPercent);
          }
          setTargetOffsetTop(targetY - mCurrentOffsetTop, true);
          break;
        }
      case MotionEventCompat.ACTION_POINTER_DOWN:
        final int index = MotionEventCompat.getActionIndex(ev);
        mActivePointerId = MotionEventCompat.getPointerId(ev, index);
        break;
      case MotionEventCompat.ACTION_POINTER_UP:
        onSecondaryPointerUp(ev);
        break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_CANCEL:
        {
          if (mActivePointerId == INVALID_POINTER) {
            return false;
          }
          final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
          final float y = MotionEventCompat.getY(ev, pointerIndex);
          final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
          mIsBeingDragged = false;
          if (overscrollTop > mTotalDragDistance) {
            setRefreshing(true, true);
          } else {
            mRefreshing = false;
            animateOffsetToStartPosition();
          }
          mActivePointerId = INVALID_POINTER;
          return false;
        }
    }

    return true;
  }