@Override
 public void applyTransformation(float interpolatedTime, Transformation t) {
   int targetTop = 0;
   int endTarget = 0;
   if (!mUsingCustomStart) {
     endTarget = (int) (mSpinnerFinalOffset - Math.abs(mOriginalOffsetTop));
   } else {
     endTarget = (int) mSpinnerFinalOffset; // mSpinnerFinalOffset;
   }
   targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
   int offset = targetTop - mCircleView.getTop();
   setTargetOffsetTopAndBottom(offset, false /* requires update */);
   mProgress.setArrowScale(1 - interpolatedTime);
 }
  private void moveSpinner(float overscrollTop) {
    mProgress.showArrow(true);
    float originalDragPercent = overscrollTop / mTotalDragDistance;

    float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
    float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;
    float extraOS = Math.abs(overscrollTop) - mTotalDragDistance;
    float slingshotDist =
        mUsingCustomStart ? mSpinnerFinalOffset - mOriginalOffsetTop : 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 = mOriginalOffsetTop + (int) ((slingshotDist * dragPercent) + extraMove);
    // where 1.0f is a full circle
    if (mCircleView.getVisibility() != View.VISIBLE) {
      mCircleView.setVisibility(View.VISIBLE);
    }
    if (!mScale) {
      ViewCompat.setScaleX(mCircleView, 1f);
      ViewCompat.setScaleY(mCircleView, 1f);
    }
    if (overscrollTop < mTotalDragDistance) {
      if (mScale) {
        setAnimationProgress(overscrollTop / mTotalDragDistance);
      }
      if (mProgress.getAlpha() > STARTING_PROGRESS_ALPHA
          && !isAnimationRunning(mAlphaStartAnimation)) {
        // Animate the alpha
        startProgressAlphaStartAnimation();
      }
      float strokeStart = adjustedPercent * .8f;
      mProgress.setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart));
      mProgress.setArrowScale(Math.min(1f, adjustedPercent));
    } else {
      if (mProgress.getAlpha() < MAX_ALPHA && !isAnimationRunning(mAlphaMaxAnimation)) {
        // Animate the alpha
        startProgressAlphaMaxAnimation();
      }
    }
    float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f;
    mProgress.setProgressRotation(rotation);
    setTargetOffsetTopAndBottom(targetY - mCurrentTargetOffsetTop, true /* requires update */);
  }