Merge "Jump drawable state (including ripples) on view detach" into lmp-dev

This commit is contained in:
Alan Viverette
2014-08-21 20:03:02 +00:00
committed by Android (Google) Code Review
4 changed files with 128 additions and 22 deletions

View File

@@ -13090,6 +13090,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
removeSendViewScrolledAccessibilityEventCallback();
stopNestedScroll();
// Anything that started animating right before detach should already
// be in its final state when re-attached.
jumpDrawablesToCurrentState();
destroyDrawingCache();
cleanupDraw();

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -198,6 +198,29 @@ public class RippleDrawable extends LayerDrawable {
initializeFromState();
}
@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();
}