summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSelim Cinek <cinek@google.com>2014-05-07 15:42:41 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-05-07 15:42:42 +0000
commit0be30834b4a4c2784bd403c22cfcbd96d404c9be (patch)
tree52ed2f7a69d255b230fedd4fa63d0350018872ca
parent010cfd458121034075c7439020ffef4eedbcc0fc (diff)
parent3af00cf10660c7fdc0582dc12361c13673d0c9bb (diff)
downloadframeworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.zip
frameworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.tar.gz
frameworks_base-0be30834b4a4c2784bd403c22cfcbd96d404c9be.tar.bz2
Merge "Improved notification scroller animation logic"
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java140
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() {