static float getAnimatedFraction(ValueAnimator animator) {
    float fraction =
        animator.getDuration() > 0
            ? ((float) animator.getCurrentPlayTime()) / animator.getDuration()
            : 0f;

    fraction = min(fraction, 1f);
    fraction = animator.getInterpolator().getInterpolation(fraction);
    return fraction;
  }
  public void onAnimationUpdate(final ValueAnimator animation) {
    final long currentTime = System.currentTimeMillis();
    if (mStartTime == -1) {
      mStartFrame = sGlobalFrameCounter;
      mStartTime = currentTime;
    }

    final long currentPlayTime = animation.getCurrentPlayTime();
    boolean isFinalFrame = Float.compare(1f, animation.getAnimatedFraction()) == 0;

    if (!mHandlingOnAnimationUpdate
        && sVisible
        &&
        // If the current play time exceeds the duration, or the animated fraction is 1,
        // the animation will get finished, even if we call setCurrentPlayTime -- therefore
        // don't adjust the animation in that case
        currentPlayTime < animation.getDuration()
        && !isFinalFrame) {
      mHandlingOnAnimationUpdate = true;
      long frameNum = sGlobalFrameCounter - mStartFrame;
      // If we haven't drawn our first frame, reset the time to t = 0
      // (give up after MAX_DELAY ms of waiting though - might happen, for example, if we
      // are no longer in the foreground and no frames are being rendered ever)
      if (frameNum == 0 && currentTime < mStartTime + MAX_DELAY && currentPlayTime > 0) {
        // The first frame on animations doesn't always trigger an invalidate...
        // force an invalidate here to make sure the animation continues to advance
        mTarget.getRootView().invalidate();
        animation.setCurrentPlayTime(0);
        // For the second frame, if the first frame took more than 16ms,
        // adjust the start time and pretend it took only 16ms anyway. This
        // prevents a large jump in the animation due to an expensive first frame
      } else if (frameNum == 1
          && currentTime < mStartTime + MAX_DELAY
          && !mAdjustedSecondFrameTime
          && currentTime > mStartTime + IDEAL_FRAME_DURATION
          && currentPlayTime > IDEAL_FRAME_DURATION) {
        animation.setCurrentPlayTime(IDEAL_FRAME_DURATION);
        mAdjustedSecondFrameTime = true;
      } else {
        if (frameNum > 1) {
          mTarget.post(
              new Runnable() {
                public void run() {
                  animation.removeUpdateListener(FirstFrameAnimatorHelper.this);
                }
              });
        }
        if (DEBUG) print(animation);
      }
      mHandlingOnAnimationUpdate = false;
    } else {
      if (DEBUG) print(animation);
    }
  }
Example #3
0
 /**
  * Returns the current duration of property animations. If the duration was set on this object,
  * that value is returned. Otherwise, the default value of the underlying Animator is returned.
  *
  * @see #setDuration(long)
  * @return The duration of animations, in milliseconds.
  */
 public long getDuration() {
   if (mDurationSet) {
     return mDuration;
   } else {
     // Just return the default from ValueAnimator, since that's what we'd get if
     // the value has not been set otherwise
     if (mTempValueAnimator == null) {
       mTempValueAnimator = new ValueAnimator();
     }
     return mTempValueAnimator.getDuration();
   }
 }
 public void print(ValueAnimator animation) {
   float flatFraction = animation.getCurrentPlayTime() / (float) animation.getDuration();
   Log.d(
       "FirstFrameAnimatorHelper",
       sGlobalFrameCounter
           + "("
           + (sGlobalFrameCounter - mStartFrame)
           + ") "
           + mTarget
           + " dirty? "
           + mTarget.isDirty()
           + " "
           + flatFraction
           + " "
           + this
           + " "
           + animation);
 }