Fix jumps in the beginning of animations
If the first draw frame of an animation is
expensive, which it often is, it causes a big
jump. Added a helper class which automatically
adjusts the animation start time if the first
frame is more than 16ms.
Change-Id: I100edbc41c2abe930a32d6bcf0a782ea9735f7f9
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index a4ed91f..545ee2e 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1240,7 +1240,7 @@
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(mReceiver, filter);
-
+ FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());
mAttached = true;
mVisible = true;
}
@@ -1269,10 +1269,9 @@
final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();
// We want to let Launcher draw itself at least once before we force it to build
// layers on all the workspace pages, so that transitioning to Launcher from other
- // apps is nice and speedy. Usually the first call to preDraw doesn't correspond to
- // a true draw so we wait until the second preDraw call to be safe
- observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
- public boolean onPreDraw() {
+ // apps is nice and speedy.
+ observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
+ public void onDraw() {
// We delay the layer building a bit in order to give
// other message processing a time to run. In particular
// this avoids a delay in hiding the IME if it was
@@ -1280,8 +1279,8 @@
// some communication back with the app.
mWorkspace.postDelayed(mBuildLayersRunnable, 500);
- observer.removeOnPreDrawListener(this);
- return true;
+ observer.removeOnDrawListener(this);
+ return;
}
});
}
@@ -2483,6 +2482,7 @@
*/
private void showAppsCustomizeHelper(final boolean animated, final boolean springLoaded) {
if (mStateAnimation != null) {
+ mStateAnimation.setDuration(0);
mStateAnimation.cancel();
mStateAnimation = null;
}
@@ -2513,7 +2513,7 @@
toView.setVisibility(View.VISIBLE);
toView.setAlpha(0f);
- final ObjectAnimator alphaAnim = ObjectAnimator
+ final ObjectAnimator alphaAnim = LauncherAnimUtils
.ofFloat(toView, "alpha", 0f, 1f)
.setDuration(fadeDuration);
alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f));
@@ -2578,7 +2578,6 @@
}
boolean delayAnim = false;
- final ViewTreeObserver observer;
dispatchOnLauncherTransitionPrepare(fromView, animated, false);
dispatchOnLauncherTransitionPrepare(toView, animated, false);
@@ -2588,10 +2587,7 @@
if ((((LauncherTransitionable) toView).getContent().getMeasuredWidth() == 0) ||
(mWorkspace.getMeasuredWidth() == 0) ||
(toView.getMeasuredWidth() == 0)) {
- observer = mWorkspace.getViewTreeObserver();
delayAnim = true;
- } else {
- observer = null;
}
final AnimatorSet stateAnimation = mStateAnimation;
@@ -2604,25 +2600,17 @@
setPivotsForZoom(toView, scale);
dispatchOnLauncherTransitionStart(fromView, animated, false);
dispatchOnLauncherTransitionStart(toView, animated, false);
- toView.post(new Runnable() {
- public void run() {
- // Check that mStateAnimation hasn't changed while
- // we waited for a layout/draw pass
- if (mStateAnimation != stateAnimation)
- return;
- mStateAnimation.start();
- }
- });
+ LauncherAnimUtils.startAnimationAfterNextDraw(mStateAnimation, toView);
}
};
if (delayAnim) {
- final OnGlobalLayoutListener delayedStart = new OnGlobalLayoutListener() {
- public void onGlobalLayout() {
- toView.post(startAnimRunnable);
- observer.removeOnGlobalLayoutListener(this);
- }
- };
- observer.addOnGlobalLayoutListener(delayedStart);
+ final ViewTreeObserver observer = toView.getViewTreeObserver();
+ observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+ public void onGlobalLayout() {
+ startAnimRunnable.run();
+ toView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ }
+ });
} else {
startAnimRunnable.run();
}
@@ -2663,6 +2651,7 @@
final boolean springLoaded, final Runnable onCompleteRunnable) {
if (mStateAnimation != null) {
+ mStateAnimation.setDuration(0);
mStateAnimation.cancel();
mStateAnimation = null;
}
@@ -2697,7 +2686,7 @@
setDuration(duration).
setInterpolator(new Workspace.ZoomInInterpolator());
- final ObjectAnimator alphaAnim = ObjectAnimator
+ final ObjectAnimator alphaAnim = LauncherAnimUtils
.ofFloat(fromView, "alpha", 1f, 0f)
.setDuration(fadeOutDuration);
alphaAnim.setInterpolator(new AccelerateDecelerateInterpolator());
@@ -2740,14 +2729,7 @@
}
dispatchOnLauncherTransitionStart(fromView, animated, true);
dispatchOnLauncherTransitionStart(toView, animated, true);
- final Animator stateAnimation = mStateAnimation;
- mWorkspace.post(new Runnable() {
- public void run() {
- if (stateAnimation != mStateAnimation)
- return;
- mStateAnimation.start();
- }
- });
+ LauncherAnimUtils.startAnimationAfterNextDraw(mStateAnimation, toView);
} else {
fromView.setVisibility(View.GONE);
dispatchOnLauncherTransitionPrepare(fromView, animated, true);