diff options
author | Selim Cinek <cinek@google.com> | 2014-05-07 15:42:41 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-07 15:42:42 +0000 |
commit | 0be30834b4a4c2784bd403c22cfcbd96d404c9be (patch) | |
tree | 52ed2f7a69d255b230fedd4fa63d0350018872ca | |
parent | 010cfd458121034075c7439020ffef4eedbcc0fc (diff) | |
parent | 3af00cf10660c7fdc0582dc12361c13673d0c9bb (diff) | |
download | frameworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.zip frameworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.tar.gz frameworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.tar.bz2 |
Merge "Improved notification scroller animation logic"
2 files changed, 79 insertions, 67 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index b72909f..f8aab80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -695,7 +695,7 @@ public class NotificationStackScrollLayout extends ViewGroup // mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity()); // } } - requestChildrenUpdate(); + updateChildren(); } // Keep on drawing until the animation has finished. @@ -705,7 +705,7 @@ public class NotificationStackScrollLayout extends ViewGroup private void customScrollTo(int y) { mOwnScrollY = y; - requestChildrenUpdate(); + updateChildren(); } @Override @@ -721,7 +721,7 @@ public class NotificationStackScrollLayout extends ViewGroup if (clampedY) { mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange()); } - requestChildrenUpdate(); + updateChildren(); } else { customScrollTo(scrollY); scrollTo(scrollX, mScrollY); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index 3281b67..2e700aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -132,10 +132,10 @@ public class StackStateAnimator { ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_HEIGHT); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, hasNewEvents); if (newDuration <= 0) { - if (previousAnimator == null) { - // no animation was running, but also no new animation should be performed, - // lets just apply the value - child.setActualHeight(viewState.height); + // no new animation needed, let's just apply the value + child.setActualHeight(viewState.height); + if (previousAnimator != null && !isRunning()) { + onAnimationFinished(); } return; } @@ -158,7 +158,7 @@ public class StackStateAnimator { child.setTag(TAG_END_HEIGHT, null); } }); - animator.start(); + startInstantly(animator); child.setTag(TAG_ANIMATOR_HEIGHT, animator); child.setTag(TAG_END_HEIGHT, viewState.height); } @@ -173,13 +173,13 @@ public class StackStateAnimator { ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_ALPHA); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, hasNewEvents); if (newDuration <= 0) { - if (previousAnimator == null) { - // no animation was running, but also no new animation should be performed, - // lets just apply the value - child.setAlpha(endAlpha); - if (endAlpha == 0) { - child.setVisibility(View.INVISIBLE); - } + // no new animation needed, let's just apply the value + child.setAlpha(endAlpha); + if (endAlpha == 0) { + child.setVisibility(View.INVISIBLE); + } + if (previousAnimator != null && !isRunning()) { + onAnimationFinished(); } return; } @@ -213,6 +213,7 @@ public class StackStateAnimator { mWasCancelled = false; } }); + animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished animator.addListener(new AnimatorListenerAdapter() { @@ -221,47 +222,11 @@ public class StackStateAnimator { } }); - animator.start(); + startInstantly(animator); child.setTag(TAG_ANIMATOR_ALPHA, animator); child.setTag(TAG_END_ALPHA, endAlpha); } - /** - * @return an adapter which ensures that onAnimationFinished is called once no animation is - * running anymore - */ - private AnimatorListenerAdapter getGlobalAnimationFinishedListener() { - if (!mAnimationListenerPool.empty()) { - return mAnimationListenerPool.pop(); - } - - // We need to create a new one, no reusable ones found - return new AnimatorListenerAdapter() { - private boolean mWasCancelled; - - @Override - public void onAnimationEnd(Animator animation) { - mAnimatorSet.remove(animation); - if (mAnimatorSet.isEmpty() && !mWasCancelled) { - onAnimationFinished(); - } - mAnimationListenerPool.push(this); - } - - @Override - public void onAnimationCancel(Animator animation) { - mWasCancelled = true; - } - - @Override - public void onAnimationStart(Animator animation) { - mAnimatorSet.add(animation); - mWasCancelled = false; - } - }; - - } - private void startZTranslationAnimation(final ExpandableView child, final StackScrollState.ViewState viewState, boolean hasNewEvents) { Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z); @@ -271,10 +236,11 @@ public class StackStateAnimator { ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Z); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, hasNewEvents); if (newDuration <= 0) { - if (previousAnimator == null) { - // no animation was running, but also no new animation should be performed, - // lets just apply the value - child.setTranslationZ(viewState.zTranslation); + // no new animation needed, let's just apply the value + child.setTranslationZ(viewState.zTranslation); + + if (previousAnimator != null && !isRunning()) { + onAnimationFinished(); } return; } @@ -282,6 +248,7 @@ public class StackStateAnimator { ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Z, child.getTranslationZ(), viewState.zTranslation); animator.setInterpolator(mFastOutSlowInInterpolator); + animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished animator.addListener(new AnimatorListenerAdapter() { @@ -291,7 +258,7 @@ public class StackStateAnimator { child.setTag(TAG_END_TRANSLATION_Z, null); } }); - animator.start(); + startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Z, animator); child.setTag(TAG_END_TRANSLATION_Z, viewState.zTranslation); } @@ -305,10 +272,10 @@ public class StackStateAnimator { ObjectAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y); long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator, hasNewEvents); if (newDuration <= 0) { - if (previousAnimator == null) { - // no animation was running, but also no new animation should be performed, - // lets just apply the value - child.setTranslationY(viewState.yTranslation); + // no new animation needed, let's just apply the value + child.setTranslationY(viewState.yTranslation); + if (previousAnimator != null && !isRunning()) { + onAnimationFinished(); } return; } @@ -316,6 +283,7 @@ public class StackStateAnimator { ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, child.getTranslationY(), viewState.yTranslation); animator.setInterpolator(mFastOutSlowInInterpolator); + animator.setDuration(newDuration); animator.addListener(getGlobalAnimationFinishedListener()); // remove the tag when the animation is finished animator.addListener(new AnimatorListenerAdapter() { @@ -325,11 +293,54 @@ public class StackStateAnimator { child.setTag(TAG_END_TRANSLATION_Y, null); } }); - animator.start(); + startInstantly(animator); child.setTag(TAG_ANIMATOR_TRANSLATION_Y, animator); child.setTag(TAG_END_TRANSLATION_Y, viewState.yTranslation); } + /** + * Start an animator instantly instead of waiting on the next synchronization frame + */ + private void startInstantly(ValueAnimator animator) { + animator.start(); + animator.setCurrentPlayTime(0); + } + + /** + * @return an adapter which ensures that onAnimationFinished is called once no animation is + * running anymore + */ + private AnimatorListenerAdapter getGlobalAnimationFinishedListener() { + if (!mAnimationListenerPool.empty()) { + return mAnimationListenerPool.pop(); + } + + // We need to create a new one, no reusable ones found + return new AnimatorListenerAdapter() { + private boolean mWasCancelled; + + @Override + public void onAnimationEnd(Animator animation) { + mAnimatorSet.remove(animation); + if (mAnimatorSet.isEmpty() && !mWasCancelled) { + onAnimationFinished(); + } + mAnimationListenerPool.push(this); + } + + @Override + public void onAnimationCancel(Animator animation) { + mWasCancelled = true; + } + + @Override + public void onAnimationStart(Animator animation) { + mAnimatorSet.add(animation); + mWasCancelled = false; + } + }; + } + private <T> T getChildTag(View child, int tag) { return (T) child.getTag(tag); } @@ -343,18 +354,19 @@ public class StackStateAnimator { */ private long cancelAnimatorAndGetNewDuration(ValueAnimator previousAnimator, boolean hasNewEvents) { + long newDuration = ANIMATION_DURATION; if (previousAnimator != null) { - previousAnimator.cancel(); if (!hasNewEvents) { // This is only an update, no new event came in. lets just take the remaining // duration as the new duration - return (long) ((1.0f - previousAnimator.getAnimatedFraction()) * - previousAnimator.getDuration()); + newDuration = previousAnimator.getDuration() + - previousAnimator.getCurrentPlayTime(); } + previousAnimator.cancel(); } else if (!hasNewEvents){ - return 0; + newDuration = 0; } - return ANIMATION_DURATION; + return newDuration; } private void onAnimationFinished() { |