diff options
author | Alan Viverette <alanv@google.com> | 2014-08-21 12:57:45 -0700 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2014-08-21 12:57:45 -0700 |
commit | d78a44576c6bac5541e04c1f38599d43c9943653 (patch) | |
tree | 48fbe6dde2327fb88492e8e29b08883225be6b5b /graphics/java | |
parent | 38dd601d0abd92a9010aa8e894f6490b445f129b (diff) | |
download | frameworks_base-d78a44576c6bac5541e04c1f38599d43c9943653.zip frameworks_base-d78a44576c6bac5541e04c1f38599d43c9943653.tar.gz frameworks_base-d78a44576c6bac5541e04c1f38599d43c9943653.tar.bz2 |
Jump drawable state (including ripples) on view detach
BUG: 15350931
Change-Id: I09928f59fb7b9f6d87b1f5219353a41ae6b5681d
Diffstat (limited to 'graphics/java')
3 files changed, 124 insertions, 22 deletions
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java index be2241b..063ac09 100644 --- a/graphics/java/android/graphics/drawable/Ripple.java +++ b/graphics/java/android/graphics/drawable/Ripple.java @@ -211,7 +211,7 @@ class Ripple { final boolean canUseHardware = c.isHardwareAccelerated(); if (mCanUseHardware != canUseHardware && mCanUseHardware) { // We've switched from hardware to non-hardware mode. Panic. - cancelHardwareAnimations(); + cancelHardwareAnimations(true); } mCanUseHardware = canUseHardware; @@ -231,7 +231,7 @@ class Ripple { final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations; final int N = pendingAnimations.size(); if (N > 0) { - cancelHardwareAnimations(); + cancelHardwareAnimations(false); for (int i = 0; i < N; i++) { pendingAnimations.get(i).setTarget(c); @@ -399,6 +399,45 @@ class Ripple { invalidateSelf(); } + public void jump() { + endSoftwareAnimations(); + endHardwareAnimations(); + } + + private void endSoftwareAnimations() { + if (mAnimRadius != null) { + mAnimRadius.end(); + } + + if (mAnimOpacity != null) { + mAnimOpacity.end(); + } + + if (mAnimX != null) { + mAnimX.end(); + } + + if (mAnimY != null) { + mAnimY.end(); + } + } + + private void endHardwareAnimations() { + final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations; + final int N = runningAnimations.size(); + for (int i = 0; i < N; i++) { + runningAnimations.get(i).end(); + } + runningAnimations.clear(); + + // Abort any pending animations. Since we always have a completion + // listener on a pending animation, we also need to remove ourselves. + if (!mPendingAnimations.isEmpty()) { + mPendingAnimations.clear(); + removeSelf(); + } + } + private Paint getTempPaint() { if (mTempPaint == null) { mTempPaint = new Paint(); @@ -444,7 +483,7 @@ class Ripple { */ public void cancel() { cancelSoftwareAnimations(); - cancelHardwareAnimations(); + cancelHardwareAnimations(true); } private void cancelSoftwareAnimations() { @@ -468,14 +507,18 @@ class Ripple { /** * Cancels any running hardware animations. */ - private void cancelHardwareAnimations() { + private void cancelHardwareAnimations(boolean cancelPending) { final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations; final int N = runningAnimations.size(); for (int i = 0; i < N; i++) { runningAnimations.get(i).cancel(); } - runningAnimations.clear(); + + if (cancelPending && !mPendingAnimations.isEmpty()) { + mPendingAnimations.clear(); + removeSelf(); + } } private void removeSelf() { diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java index 93df648..49862bc 100644 --- a/graphics/java/android/graphics/drawable/RippleBackground.java +++ b/graphics/java/android/graphics/drawable/RippleBackground.java @@ -203,7 +203,7 @@ class RippleBackground { final boolean canUseHardware = c.isHardwareAccelerated(); if (mCanUseHardware != canUseHardware && mCanUseHardware) { // We've switched from hardware to non-hardware mode. Panic. - cancelHardwareAnimations(); + cancelHardwareAnimations(true); } mCanUseHardware = canUseHardware; @@ -223,7 +223,7 @@ class RippleBackground { final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations; final int N = pendingAnimations.size(); if (N > 0) { - cancelHardwareAnimations(); + cancelHardwareAnimations(false); for (int i = 0; i < N; i++) { pendingAnimations.get(i).setTarget(c); @@ -403,6 +403,41 @@ class RippleBackground { invalidateSelf(); } + public void jump() { + endSoftwareAnimations(); + endHardwareAnimations(); + } + + private void endSoftwareAnimations() { + if (mAnimOuterOpacity != null) { + mAnimOuterOpacity.end(); + } + + if (mAnimX != null) { + mAnimX.end(); + } + + if (mAnimY != null) { + mAnimY.end(); + } + } + + private void endHardwareAnimations() { + final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations; + final int N = runningAnimations.size(); + for (int i = 0; i < N; i++) { + runningAnimations.get(i).end(); + } + runningAnimations.clear(); + + // Abort any pending animations. Since we always have a completion + // listener on a pending animation, we also need to remove ourselves. + if (!mPendingAnimations.isEmpty()) { + mPendingAnimations.clear(); + removeSelf(); + } + } + private Paint getTempPaint() { if (mTempPaint == null) { mTempPaint = new Paint(); @@ -477,7 +512,7 @@ class RippleBackground { */ public void cancel() { cancelSoftwareAnimations(); - cancelHardwareAnimations(); + cancelHardwareAnimations(true); } private void cancelSoftwareAnimations() { @@ -497,7 +532,7 @@ class RippleBackground { /** * Cancels any running hardware animations. */ - private void cancelHardwareAnimations() { + private void cancelHardwareAnimations(boolean cancelPending) { final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations; final int N = runningAnimations.size(); for (int i = 0; i < N; i++) { @@ -505,6 +540,11 @@ class RippleBackground { } runningAnimations.clear(); + + if (cancelPending && !mPendingAnimations.isEmpty()) { + mPendingAnimations.clear(); + removeSelf(); + } } private void removeSelf() { diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 0447e17..ca32751 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -199,6 +199,29 @@ public class RippleDrawable extends LayerDrawable { } @Override + public void jumpToCurrentState() { + super.jumpToCurrentState(); + + if (mRipple != null) { + mRipple.jump(); + } + + if (mBackground != null) { + mBackground.jump(); + } + + mClearingHotspots = true; + final int count = mAnimatingRipplesCount; + final Ripple[] ripples = mAnimatingRipples; + for (int i = 0; i < count; i++) { + ripples[i].jump(); + ripples[i] = null; + } + mAnimatingRipplesCount = 0; + mClearingHotspots = false; + } + + @Override public void setAlpha(int alpha) { super.setAlpha(alpha); @@ -534,18 +557,6 @@ public class RippleDrawable extends LayerDrawable { } private void clearHotspots() { - mClearingHotspots = true; - - final int count = mAnimatingRipplesCount; - final Ripple[] ripples = mAnimatingRipples; - for (int i = 0; i < count; i++) { - // Calling cancel may remove the ripple from the animating ripple - // array, so cache the reference before nulling it out. - final Ripple ripple = ripples[i]; - ripples[i] = null; - ripple.cancel(); - } - if (mRipple != null) { mRipple.cancel(); mRipple = null; @@ -556,8 +567,16 @@ public class RippleDrawable extends LayerDrawable { mBackground = null; } - mClearingHotspots = false; + mClearingHotspots = true; + final int count = mAnimatingRipplesCount; + final Ripple[] ripples = mAnimatingRipples; + for (int i = 0; i < count; i++) { + ripples[i].cancel(); + ripples[i] = null; + } mAnimatingRipplesCount = 0; + mClearingHotspots = false; + invalidateSelf(); } |