diff options
author | Michael Jurka <mikejurka@google.com> | 2013-04-08 18:28:15 -0700 |
---|---|---|
committer | Arne Coucheron <arco68@gmail.com> | 2013-08-12 16:55:05 +0200 |
commit | bf79d513be562cdec61424336087cd0ddf8cdc12 (patch) | |
tree | e68c601c4aeb7dadfba0dedb6dd06b8eafdea80d /src/com/cyanogenmod/trebuchet | |
parent | e36bef0ca63bc81b4e131ef3054c87db8b52a8cb (diff) | |
download | android_packages_apps_Trebuchet-bf79d513be562cdec61424336087cd0ddf8cdc12.tar.gz android_packages_apps_Trebuchet-bf79d513be562cdec61424336087cd0ddf8cdc12.tar.bz2 android_packages_apps_Trebuchet-bf79d513be562cdec61424336087cd0ddf8cdc12.zip |
Fix bug where folder open animation gets finished early
Also, sync FirstFrameAnimatorHelper with changes
made in Recents
Bug: 8530231
Change-Id: Ibf1a43f67d91df89a2338f0f0c0fb52ee5496e57
Diffstat (limited to 'src/com/cyanogenmod/trebuchet')
-rw-r--r-- | src/com/cyanogenmod/trebuchet/FirstFrameAnimatorHelper.java | 52 | ||||
-rw-r--r-- | src/com/cyanogenmod/trebuchet/LauncherViewPropertyAnimator.java | 16 |
2 files changed, 49 insertions, 19 deletions
diff --git a/src/com/cyanogenmod/trebuchet/FirstFrameAnimatorHelper.java b/src/com/cyanogenmod/trebuchet/FirstFrameAnimatorHelper.java index c7a864300..1b1c355db 100644 --- a/src/com/cyanogenmod/trebuchet/FirstFrameAnimatorHelper.java +++ b/src/com/cyanogenmod/trebuchet/FirstFrameAnimatorHelper.java @@ -16,20 +16,24 @@ package com.cyanogenmod.trebuchet; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.Animator.AnimatorListener; import android.util.Log; import android.view.ViewTreeObserver; import android.view.View; +import android.view.ViewPropertyAnimator; /* * This is a helper class that listens to updates from the corresponding animation. * For the first two frames, it adjusts the current play time of the animation to * prevent jank at the beginning of the animation */ -public class FirstFrameAnimatorHelper implements ValueAnimator.AnimatorUpdateListener { +public class FirstFrameAnimatorHelper extends AnimatorListenerAdapter + implements ValueAnimator.AnimatorUpdateListener { private static final boolean DEBUG = false; - private static final int MAX_FIRST_FRAME_DELAY = 200; + private static final int MAX_DELAY = 1000; private static final int IDEAL_FRAME_DURATION = 16; private View mTarget; private long mStartFrame; @@ -45,43 +49,65 @@ public class FirstFrameAnimatorHelper implements ValueAnimator.AnimatorUpdateLis animator.addUpdateListener(this); } + public FirstFrameAnimatorHelper(ViewPropertyAnimator vpa, View target) { + mTarget = target; + vpa.setListener(this); + } + + // only used for ViewPropertyAnimators + public void onAnimationStart(Animator animation) { + final ValueAnimator va = (ValueAnimator) animation; + va.addUpdateListener(FirstFrameAnimatorHelper.this); + onAnimationUpdate(va); + } + public static void initializeDrawListener(View view) { + if (sGlobalDrawListener != null) { + view.getViewTreeObserver().removeOnDrawListener(sGlobalDrawListener); + } sGlobalDrawListener = new ViewTreeObserver.OnDrawListener() { private long mTime = System.currentTimeMillis(); public void onDraw() { sGlobalFrameCounter++; - long newTime = System.currentTimeMillis(); if (DEBUG) { + long newTime = System.currentTimeMillis(); Log.d("FirstFrameAnimatorHelper", "TICK " + (newTime - mTime)); + mTime = newTime; } - mTime = newTime; } }; view.getViewTreeObserver().addOnDrawListener(sGlobalDrawListener); } public void onAnimationUpdate(final ValueAnimator animation) { + final long currentTime = System.currentTimeMillis(); if (mStartTime == -1) { mStartFrame = sGlobalFrameCounter; - mStartTime = System.currentTimeMillis(); + mStartTime = currentTime; } - if (!mHandlingOnAnimationUpdate) { + 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 200ms 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 && System.currentTimeMillis() < mStartTime + MAX_FIRST_FRAME_DELAY) { - mTarget.getRootView().invalidate(); // make sure we'll do a draw + // (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 && !mAdjustedSecondFrameTime && - System.currentTimeMillis() > mStartTime + 16) { + } else if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && + !mAdjustedSecondFrameTime && + currentTime > mStartTime + IDEAL_FRAME_DURATION) { animation.setCurrentPlayTime(IDEAL_FRAME_DURATION); mAdjustedSecondFrameTime = true; } else { diff --git a/src/com/cyanogenmod/trebuchet/LauncherViewPropertyAnimator.java b/src/com/cyanogenmod/trebuchet/LauncherViewPropertyAnimator.java index d4838ec9e..cd9ef8381 100644 --- a/src/com/cyanogenmod/trebuchet/LauncherViewPropertyAnimator.java +++ b/src/com/cyanogenmod/trebuchet/LauncherViewPropertyAnimator.java @@ -55,6 +55,7 @@ public class LauncherViewPropertyAnimator extends Animator implements AnimatorLi TimeInterpolator mInterpolator; ArrayList<Animator.AnimatorListener> mListeners; boolean mRunning = false; + FirstFrameAnimatorHelper mFirstFrameHelper; public LauncherViewPropertyAnimator(View target) { mTarget = target; @@ -126,12 +127,10 @@ public class LauncherViewPropertyAnimator extends Animator implements AnimatorLi @Override public void onAnimationStart(Animator animation) { - // This is the first time we get a handle to the internal ValueAnimator - // used by the ViewPropertyAnimator. - // FirstFrameAnimatorHelper hooks itself up to the updates on the animator, - // and then adjusts the play time to keep the first two frames jank-free - new FirstFrameAnimatorHelper((ValueAnimator) animation, mTarget) - .onAnimationUpdate((ValueAnimator) animation); + // This is the first time we get a handle to the internal ValueAnimator + // used by the ViewPropertyAnimator. + mFirstFrameHelper.onAnimationStart(animation); + for (int i = 0; i < mListeners.size(); i++) { Animator.AnimatorListener listener = mListeners.get(i); listener.onAnimationStart(this); @@ -195,6 +194,11 @@ public class LauncherViewPropertyAnimator extends Animator implements AnimatorLi @Override public void start() { mViewPropertyAnimator = mTarget.animate(); + + // FirstFrameAnimatorHelper hooks itself up to the updates on the animator, + // and then adjusts the play time to keep the first two frames jank-free + mFirstFrameHelper = new FirstFrameAnimatorHelper(mViewPropertyAnimator, mTarget); + if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) { mViewPropertyAnimator.translationX(mTranslationX); } |