title: How to create Accelerate - Linear - Decelerate animation effect in android using ValueAnimator?
body: <p>Now I have to create an animation of a spinning fan. When user click POWER ON button, this fan begin to spin, then keep it's spinning speed at some level.When user click POWER OFF button, it slowing down then it stop.</p>
  
  <p>I make some code as follows：</p>
  
  <pre><code>ImageView mFanImageview;
  private ValueAnimator mFanValueAnimator;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_centripetal_particle);
      ButterKnife.bind(this);
  }
  
  private void startFan() {
      mFanValueAnimator = new ValueAnimator();
      mFanValueAnimator.setDuration(1000);
      mFanValueAnimator.setFloatValues(mFanImageview.getRotation(), mFanImageview.getRotation() + 360);
      mFanValueAnimator.setInterpolator(new AccelerateInterpolator());
      mFanValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
              mFanImageview.setRotation((Float) animation.getAnimatedValue());
          }
      });
      mFanValueAnimator.addListener(new AnimatorListenerAdapter() {
          @Override
          public void onAnimationEnd(Animator animation) {
              mFanValueAnimator = new ValueAnimator();
              mFanValueAnimator.setDuration(500);
              mFanValueAnimator.setFloatValues(mFanImageview.getRotation(), mFanImageview.getRotation() + 360);
              mFanValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
              mFanValueAnimator.setRepeatMode(ValueAnimator.RESTART);
              mFanValueAnimator.setInterpolator(new LinearInterpolator());
              mFanValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                  @Override
                  public void onAnimationUpdate(ValueAnimator animation) {
                      mFanImageview.setRotation((Float) animation.getAnimatedValue());
                  }
              });
              mFanValueAnimator.addListener(new AnimatorListenerAdapter() {
                  @Override
                  public void onAnimationCancel(Animator animation) {
                      stopFanValueAnimator().start();
                  }
              });
              mFanValueAnimator.start();
          }
  
          @Override
          public void onAnimationCancel(Animator animation) {
              stopFanValueAnimator().start();
          }
      });
      mFanValueAnimator.start();
  }
  
  private ValueAnimator stopFanValueAnimator() {
      ValueAnimator stopAnimator = new ValueAnimator();
      stopAnimator.setDuration(1000);
      stopAnimator.setFloatValues(mFanImageview.getRotation(), mFanImageview.getRotation() + 360);
      stopAnimator.setInterpolator(new DecelerateInterpolator());
      stopAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
              mFanImageview.setRotation((Float) animation.getAnimatedValue());
          }
      });
      return stopAnimator;
  }
  
  @OnClick(R.id.stop_button)
  public void onStopButtonClicked() {
      mFanValueAnimator.cancel();
  }
  
  @OnClick(R.id.start_button)
  public void onStartButtonClicked() {
      startFan();
  }
  </code></pre>
  
  <p>The animation above seems ok, but I found that the fan spinning speed at the end of AccelerateInterpolator animator is hard to match the beginning of LinearInterpolator.I have to adjust duration of LinearInterpolator animator carefully.</p>
  
  <p>How can I get the update rate at the end of AccelerateInterpolator animator then set the right duration of LinearInterpolator animator? </p>