FileDocCategorySizeDatePackage
FirstFrameAnimatorHelper.javaAPI DocAndroid 5.1 API5817Thu Mar 12 22:22:42 GMT 2015com.android.systemui.recent

FirstFrameAnimatorHelper

public class FirstFrameAnimatorHelper extends android.animation.AnimatorListenerAdapter implements ValueAnimator.AnimatorUpdateListener

Fields Summary
private static final boolean
DEBUG
private static final int
MAX_DELAY
private static final int
IDEAL_FRAME_DURATION
private android.view.View
mTarget
private long
mStartFrame
private long
mStartTime
private boolean
mHandlingOnAnimationUpdate
private boolean
mAdjustedSecondFrameTime
private static ViewTreeObserver.OnDrawListener
sGlobalDrawListener
private static long
sGlobalFrameCounter
Constructors Summary
public FirstFrameAnimatorHelper(android.animation.ValueAnimator animator, android.view.View target)


         
        mTarget = target;
        animator.addUpdateListener(this);
    
public FirstFrameAnimatorHelper(android.view.ViewPropertyAnimator vpa, android.view.View target)

        mTarget = target;
        vpa.setListener(this);
    
Methods Summary
public static voidinitializeDrawListener(android.view.View view)

        if (sGlobalDrawListener != null) {
            view.getViewTreeObserver().removeOnDrawListener(sGlobalDrawListener);
        }
        sGlobalDrawListener = new ViewTreeObserver.OnDrawListener() {
                private long mTime = System.currentTimeMillis();
                public void onDraw() {
                    sGlobalFrameCounter++;
                    if (DEBUG) {
                        long newTime = System.currentTimeMillis();
                        Log.d("FirstFrameAnimatorHelper", "TICK " + (newTime - mTime));
                        mTime = newTime;
                    }
                }
            };
        view.getViewTreeObserver().addOnDrawListener(sGlobalDrawListener);
    
public voidonAnimationStart(android.animation.Animator animation)

        final ValueAnimator va = (ValueAnimator) animation;
        va.addUpdateListener(FirstFrameAnimatorHelper.this);
        onAnimationUpdate(va);
    
public voidonAnimationUpdate(android.animation.ValueAnimator animation)

        final long currentTime = System.currentTimeMillis();
        if (mStartTime == -1) {
            mStartFrame = sGlobalFrameCounter;
            mStartTime = currentTime;
        }

        if (!mHandlingOnAnimationUpdate &&
            // If the current play time exceeds the duration, the animation
            // will get finished, even if we call setCurrentPlayTime -- therefore
            // don't adjust the animation in that case
            animation.getCurrentPlayTime() < animation.getDuration()) {
            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) {
                // 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) {
                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);
        }
    
public voidprint(android.animation.ValueAnimator animation)

        float flatFraction = animation.getCurrentPlayTime() / (float) animation.getDuration();
        Log.d("FirstFrameAnimatorHelper", sGlobalFrameCounter +
              "(" + (sGlobalFrameCounter - mStartFrame) + ") " + mTarget + " dirty? " +
              mTarget.isDirty() + " " + flatFraction + " " + this + " " + animation);