From 41bff38d3060dbcb55133cedaf5d962c3082efc2 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Mon, 29 Aug 2011 16:00:23 -0700 Subject: [PATCH] Tweaks to NotificationPanel animation The animation that runs when the NotificationPanel appears used to start, then pause for a long time as the window/surface/layer was created, then by the time it started to be visible, the animation was over. This new approach delays starting the animation until the layer has been drawn, so the animation can actually run a few frames after that before finishing. Change-Id: I998f01fd48cb762178021ad99e2b919b58a1ef3f --- .../graphics/drawable/ColorDrawable.java | 5 ++- .../statusbar/tablet/NotificationPanel.java | 43 +++++++++++++------ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 4418e02a89f52..88c91559dcbbf 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -111,8 +111,11 @@ public class ColorDrawable extends Drawable { alpha += alpha >> 7; // make it 0..256 int baseAlpha = mState.mBaseColor >>> 24; int useAlpha = baseAlpha * alpha >> 8; + int oldUseColor = mState.mUseColor; mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24); - invalidateSelf(); + if (oldUseColor != mState.mUseColor) { + invalidateSelf(); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java index d9cb4e8678b9a..4a1cafdcce6e7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java @@ -28,6 +28,10 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; import android.widget.RelativeLayout; import com.android.systemui.R; @@ -52,6 +56,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, ViewGroup mContentParent; TabletStatusBar mBar; View mClearButton; + static Interpolator sAccelerateInterpolator = new AccelerateInterpolator(); + static Interpolator sDecelerateInterpolator = new DecelerateInterpolator(); // amount to slide mContentParent down by when mContentFrame is missing float mContentFrameMissingTranslation; @@ -117,8 +123,13 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, mShowing = show; if (show) { setVisibility(View.VISIBLE); + // Don't start the animation until we've created the layer, which is done + // right before we are drawn + mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null); + getViewTreeObserver().addOnPreDrawListener(mPreDrawListener); + } else { + mChoreo.startAnimation(show); } - mChoreo.startAnimation(show); } } else { mShowing = show; @@ -126,6 +137,20 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, } } + /** + * This is used only when we've created a hardware layer and are waiting until it's + * been created in order to start the appearing animation. + */ + private ViewTreeObserver.OnPreDrawListener mPreDrawListener = + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + getViewTreeObserver().removeOnPreDrawListener(this); + mChoreo.startAnimation(true); + return true; + } + }; + /** * Whether the panel is showing, or, if it's animating, whether it will be * when the animation is done. @@ -330,8 +355,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, AnimatorSet mContentAnim; // should group this into a multi-property animation - final static int OPEN_DURATION = 300; - final static int CLOSE_DURATION = 300; + final static int OPEN_DURATION = 250; + final static int CLOSE_DURATION = 250; // the panel will start to appear this many px from the end final int HYPERSPACE_OFFRAMP = 200; @@ -362,19 +387,15 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY", start, end); - posAnim.setInterpolator(appearing - ? new android.view.animation.DecelerateInterpolator(1.0f) - : new android.view.animation.AccelerateInterpolator(1.0f)); + posAnim.setInterpolator(appearing ? sDecelerateInterpolator : sAccelerateInterpolator); if (mContentAnim != null && mContentAnim.isRunning()) { mContentAnim.cancel(); } Animator fadeAnim = ObjectAnimator.ofFloat(mContentParent, "alpha", - mContentParent.getAlpha(), appearing ? 1.0f : 0.0f); - fadeAnim.setInterpolator(appearing - ? new android.view.animation.AccelerateInterpolator(2.0f) - : new android.view.animation.DecelerateInterpolator(2.0f)); + appearing ? 1.0f : 0.0f); + fadeAnim.setInterpolator(appearing ? sAccelerateInterpolator : sDecelerateInterpolator); mContentAnim = new AnimatorSet(); mContentAnim @@ -389,8 +410,6 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")"); createAnimation(appearing); - - mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null); mContentAnim.start(); mVisible = appearing;