16ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette/* 26ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Copyright (C) 2013 The Android Open Source Project 36ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * 46ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 56ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * you may not use this file except in compliance with the License. 66ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * You may obtain a copy of the License at 76ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * 86ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * http://www.apache.org/licenses/LICENSE-2.0 96ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * 106ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Unless required by applicable law or agreed to in writing, software 116ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 126ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * See the License for the specific language governing permissions and 146ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * limitations under the License. 156ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 166ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 176ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverettepackage android.graphics.drawable; 186ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 196ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.animation.Animator; 206ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.animation.AnimatorListenerAdapter; 216ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.animation.ObjectAnimator; 226ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.animation.TimeInterpolator; 236ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.graphics.Canvas; 246ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.graphics.CanvasProperty; 25a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viveretteimport android.graphics.Color; 266ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.graphics.Paint; 276ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.graphics.Rect; 286ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.util.MathUtils; 296ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.view.HardwareCanvas; 306ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.view.RenderNodeAnimator; 316ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport android.view.animation.LinearInterpolator; 326ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 336ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteimport java.util.ArrayList; 346ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 356ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette/** 366ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Draws a Material ripple. 376ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 386ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viveretteclass RippleBackground { 396ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); 406ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 416ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private static final float GLOBAL_SPEED = 1.0f; 426ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private static final float WAVE_OPACITY_DECAY_VELOCITY = 3.0f / GLOBAL_SPEED; 437ff48839b0149eba1ab46cfd1476854c2e664a81Alan Viverette private static final float WAVE_OUTER_OPACITY_EXIT_VELOCITY_MAX = 4.5f * GLOBAL_SPEED; 447ff48839b0149eba1ab46cfd1476854c2e664a81Alan Viverette private static final float WAVE_OUTER_OPACITY_EXIT_VELOCITY_MIN = 1.5f * GLOBAL_SPEED; 456ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private static final float WAVE_OUTER_SIZE_INFLUENCE_MAX = 200f; 466ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private static final float WAVE_OUTER_SIZE_INFLUENCE_MIN = 40f; 476ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 48f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette private static final int ENTER_DURATION = 667; 49f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette private static final int ENTER_DURATION_FAST = 100; 50f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette 516ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Hardware animators. 526ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private final ArrayList<RenderNodeAnimator> mRunningAnimations = 536ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette new ArrayList<RenderNodeAnimator>(); 546ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 556ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private final RippleDrawable mOwner; 566ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 576ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Bounds used for computing max radius. */ 586ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private final Rect mBounds; 596ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 60cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette /** ARGB color for drawing this ripple. */ 61cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette private int mColor; 62a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette 636ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Maximum ripple radius. */ 646ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private float mOuterRadius; 656ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 666ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Screen density used to adjust pixel-based velocities. */ 676ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private float mDensity; 686ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 696ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Hardware rendering properties. 706ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private CanvasProperty<Paint> mPropOuterPaint; 716ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private CanvasProperty<Float> mPropOuterRadius; 726ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private CanvasProperty<Float> mPropOuterX; 736ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private CanvasProperty<Float> mPropOuterY; 746ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 756ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Software animators. 766ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private ObjectAnimator mAnimOuterOpacity; 776ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 786ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Temporary paint used for creating canvas properties. 796ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private Paint mTempPaint; 806ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 816ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Software rendering properties. 826ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private float mOuterOpacity = 0; 836ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private float mOuterX; 846ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private float mOuterY; 856ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 866ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Whether we should be drawing hardware animations. */ 876ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private boolean mHardwareAnimating; 886ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 896ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Whether we can use hardware acceleration for the exit animation. */ 906ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private boolean mCanUseHardware; 916ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 926ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** Whether we have an explicit maximum radius. */ 936ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private boolean mHasMaxRadius; 946ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 956dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private boolean mHasPendingHardwareExit; 966dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private int mPendingOpacityDuration; 976dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private int mPendingInflectionDuration; 986dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private int mPendingInflectionOpacity; 996dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette 1006ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 1016ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Creates a new ripple. 1026ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 103a8a8ff000b2902eb4e187e62be39fd9535c6c839Alan Viverette public RippleBackground(RippleDrawable owner, Rect bounds) { 1046ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOwner = owner; 1056ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mBounds = bounds; 1066ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1076ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 108cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette public void setup(int maxRadius, float density) { 1096ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (maxRadius != RippleDrawable.RADIUS_AUTO) { 1106ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mHasMaxRadius = true; 1116ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterRadius = maxRadius; 1126ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 1136ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final float halfWidth = mBounds.width() / 2.0f; 1146ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final float halfHeight = mBounds.height() / 2.0f; 1156ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterRadius = (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight); 1166ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1176ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1186ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterX = 0; 1196ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterY = 0; 1206ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mDensity = density; 1216ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1226ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1236ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void onHotspotBoundsChanged() { 1246ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (!mHasMaxRadius) { 1256ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final float halfWidth = mBounds.width() / 2.0f; 1266ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final float halfHeight = mBounds.height() / 2.0f; 1276ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterRadius = (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight); 1286ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1296ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1306ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1316ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette @SuppressWarnings("unused") 1326ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void setOuterOpacity(float a) { 1336ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOuterOpacity = a; 1346ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette invalidateSelf(); 1356ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1366ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1376ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette @SuppressWarnings("unused") 1386ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public float getOuterOpacity() { 1396ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette return mOuterOpacity; 1406ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1416ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1426ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 1436ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Draws the ripple centered at (0,0) using the specified paint. 1446ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 1456ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public boolean draw(Canvas c, Paint p) { 146cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette mColor = p.getColor(); 147cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette 1486ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final boolean canUseHardware = c.isHardwareAccelerated(); 1496ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (mCanUseHardware != canUseHardware && mCanUseHardware) { 1506ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // We've switched from hardware to non-hardware mode. Panic. 151a0c0ca738989fd3ecad8a54a91f0c6a8b30ad1abAlan Viverette cancelHardwareAnimations(true); 1526ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1536ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mCanUseHardware = canUseHardware; 1546ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1556ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final boolean hasContent; 1566dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette if (canUseHardware && (mHardwareAnimating || mHasPendingHardwareExit)) { 1576dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette hasContent = drawHardware((HardwareCanvas) c, p); 1586ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 1596ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette hasContent = drawSoftware(c, p); 1606ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1616ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1626ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette return hasContent; 1636ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1646ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 165a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette public boolean shouldDraw() { 166cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette return (mCanUseHardware && mHardwareAnimating) || (mOuterOpacity > 0 && mOuterRadius > 0); 167a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette } 168a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette 1696dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private boolean drawHardware(HardwareCanvas c, Paint p) { 1706dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette if (mHasPendingHardwareExit) { 171d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette cancelHardwareAnimations(false); 1726dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette startPendingHardwareExit(c, p); 1736ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1746ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1756ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette c.drawCircle(mPropOuterX, mPropOuterY, mPropOuterRadius, mPropOuterPaint); 1766ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1776ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette return true; 1786ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1796ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1806ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private boolean drawSoftware(Canvas c, Paint p) { 1816ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette boolean hasContent = false; 1826ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 183cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette final int paintAlpha = p.getAlpha(); 184cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette final int alpha = (int) (paintAlpha * mOuterOpacity + 0.5f); 185cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette final float radius = mOuterRadius; 186cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette if (alpha > 0 && radius > 0) { 187cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette p.setAlpha(alpha); 188cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette c.drawCircle(mOuterX, mOuterY, radius, p); 189cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette p.setAlpha(paintAlpha); 1906ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette hasContent = true; 1916ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1926ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1936ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette return hasContent; 1946ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 1956ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 1966ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 1976ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Returns the maximum bounds of the ripple relative to the ripple center. 1986ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 1996ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void getBounds(Rect bounds) { 2006ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final int outerX = (int) mOuterX; 2016ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final int outerY = (int) mOuterY; 202036a66596dba32c051a016ca9b5334fbbd39c220Alan Viverette final int r = (int) mOuterRadius + 1; 2036ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette bounds.set(outerX - r, outerY - r, outerX + r, outerY + r); 2046ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 2056ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2066ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 2076ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Starts the enter animation. 2086ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 209f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette public void enter(boolean fast) { 210fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette cancel(); 211fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette 212f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette final ObjectAnimator opacity = ObjectAnimator.ofFloat(this, "outerOpacity", 0, 1); 213f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette opacity.setAutoCancel(true); 214f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette opacity.setDuration(fast ? ENTER_DURATION_FAST : ENTER_DURATION); 215f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette opacity.setInterpolator(LINEAR_INTERPOLATOR); 2166ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 217f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette mAnimOuterOpacity = opacity; 2186ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2196ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Enter animations always run on the UI thread, since it's unlikely 2206ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // that anything interesting is happening until the user lifts their 2216ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // finger. 222f92f26fef215897bd302c1c06adbe5d853881b3fAlan Viverette opacity.start(); 2236ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 2246ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2256ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 2266ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Starts the exit animation. 2276ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 2286ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void exit() { 229fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette cancel(); 2306ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2316ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Scale the outer max opacity and opacity velocity based 2326ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // on the size of the outer radius. 2336ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final int opacityDuration = (int) (1000 / WAVE_OPACITY_DECAY_VELOCITY + 0.5f); 2346ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final float outerSizeInfluence = MathUtils.constrain( 2356ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette (mOuterRadius - WAVE_OUTER_SIZE_INFLUENCE_MIN * mDensity) 2366ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette / (WAVE_OUTER_SIZE_INFLUENCE_MAX * mDensity), 0, 1); 2377ff48839b0149eba1ab46cfd1476854c2e664a81Alan Viverette final float outerOpacityVelocity = MathUtils.lerp(WAVE_OUTER_OPACITY_EXIT_VELOCITY_MIN, 2387ff48839b0149eba1ab46cfd1476854c2e664a81Alan Viverette WAVE_OUTER_OPACITY_EXIT_VELOCITY_MAX, outerSizeInfluence); 2396ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2406ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Determine at what time the inner and outer opacity intersect. 2416ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // inner(t) = mOpacity - t * WAVE_OPACITY_DECAY_VELOCITY / 1000 2426ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // outer(t) = mOuterOpacity + t * WAVE_OUTER_OPACITY_VELOCITY / 1000 243a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette final int inflectionDuration = Math.max(0, (int) (1000 * (1 - mOuterOpacity) 2446ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette / (WAVE_OPACITY_DECAY_VELOCITY + outerOpacityVelocity) + 0.5f)); 245cc3c573334a9cd2124a8a0ccf2f37884e36f83faAlan Viverette final int inflectionOpacity = (int) (Color.alpha(mColor) * (mOuterOpacity 246a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette + inflectionDuration * outerOpacityVelocity * outerSizeInfluence / 1000) + 0.5f); 2476ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2486ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (mCanUseHardware) { 2496dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette createPendingHardwareExit(opacityDuration, inflectionDuration, inflectionOpacity); 2506ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 251a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette exitSoftware(opacityDuration, inflectionDuration, inflectionOpacity); 2526ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 2536ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 2546ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2556dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private void createPendingHardwareExit( 2566dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette int opacityDuration, int inflectionDuration, int inflectionOpacity) { 2576dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mHasPendingHardwareExit = true; 2586dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mPendingOpacityDuration = opacityDuration; 2596dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mPendingInflectionDuration = inflectionDuration; 2606dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mPendingInflectionOpacity = inflectionOpacity; 2616dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette 2626dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette // The animation will start on the next draw(). 2636dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette invalidateSelf(); 2646dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette } 2656dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette 2666dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private void startPendingHardwareExit(HardwareCanvas c, Paint p) { 2676dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mHasPendingHardwareExit = false; 2686dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette 2696dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette final int opacityDuration = mPendingOpacityDuration; 2706dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette final int inflectionDuration = mPendingInflectionDuration; 2716dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette final int inflectionOpacity = mPendingInflectionOpacity; 2726ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2736dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette final Paint outerPaint = getTempPaint(p); 2746dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette outerPaint.setAlpha((int) (outerPaint.getAlpha() * mOuterOpacity + 0.5f)); 2756ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterPaint = CanvasProperty.createPaint(outerPaint); 2766ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterRadius = CanvasProperty.createFloat(mOuterRadius); 2776ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterX = CanvasProperty.createFloat(mOuterX); 2786ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterY = CanvasProperty.createFloat(mOuterY); 2796ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2806ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final RenderNodeAnimator outerOpacityAnim; 281a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette if (inflectionDuration > 0) { 2826ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Outer opacity continues to increase for a bit. 283a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette outerOpacityAnim = new RenderNodeAnimator(mPropOuterPaint, 284a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette RenderNodeAnimator.PAINT_ALPHA, inflectionOpacity); 285a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette outerOpacityAnim.setDuration(inflectionDuration); 2866ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setInterpolator(LINEAR_INTERPOLATOR); 2876ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 2886ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Chain the outer opacity exit animation. 289a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette final int outerDuration = opacityDuration - inflectionDuration; 2906ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (outerDuration > 0) { 2916ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final RenderNodeAnimator outerFadeOutAnim = new RenderNodeAnimator( 2926ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterPaint, RenderNodeAnimator.PAINT_ALPHA, 0); 2936ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setDuration(outerDuration); 2946ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setInterpolator(LINEAR_INTERPOLATOR); 295a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette outerFadeOutAnim.setStartDelay(inflectionDuration); 2966ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setStartValue(inflectionOpacity); 2976ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.addListener(mAnimationListener); 2986dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette outerFadeOutAnim.setTarget(c); 2996dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette outerFadeOutAnim.start(); 3006ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3016dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mRunningAnimations.add(outerFadeOutAnim); 3026ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 3036ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.addListener(mAnimationListener); 3046ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3056ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 3066ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim = new RenderNodeAnimator( 3076ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mPropOuterPaint, RenderNodeAnimator.PAINT_ALPHA, 0); 3086ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setInterpolator(LINEAR_INTERPOLATOR); 3096ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setDuration(opacityDuration); 3106ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.addListener(mAnimationListener); 3116ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3126ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3136dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette outerOpacityAnim.setTarget(c); 3146dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette outerOpacityAnim.start(); 3156dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette 3166dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mRunningAnimations.add(outerOpacityAnim); 3176ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3186ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mHardwareAnimating = true; 3196ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 320be0dd99bac781d1dd73cb67f33bcd931e3693af5Alan Viverette // Set up the software values to match the hardware end values. 321be0dd99bac781d1dd73cb67f33bcd931e3693af5Alan Viverette mOuterOpacity = 0; 3226ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3236ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 324fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette /** 325fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette * Jump all animations to their end state. The caller is responsible for 326fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette * removing the ripple from the list of animating ripples. 327fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette */ 328d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette public void jump() { 329d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette endSoftwareAnimations(); 330a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette cancelHardwareAnimations(true); 331d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette } 332d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette 333d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette private void endSoftwareAnimations() { 334d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette if (mAnimOuterOpacity != null) { 335d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette mAnimOuterOpacity.end(); 336a2362c9251af9d27506aa12f49da42e019665555Alan Viverette mAnimOuterOpacity = null; 337d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette } 338d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette } 339d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette 3406dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette private Paint getTempPaint(Paint original) { 3416ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (mTempPaint == null) { 3426ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mTempPaint = new Paint(); 3436ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3446dfa60f33ca6018959ebff1efde82db7d2aed1e3Alan Viverette mTempPaint.set(original); 3456ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette return mTempPaint; 3466ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3476ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 348a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette private void exitSoftware(int opacityDuration, int inflectionDuration, int inflectionOpacity) { 3496ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final ObjectAnimator outerOpacityAnim; 350a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette if (inflectionDuration > 0) { 3516ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Outer opacity continues to increase for a bit. 3526ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim = ObjectAnimator.ofFloat(this, 3536ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette "outerOpacity", inflectionOpacity / 255.0f); 3546ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setAutoCancel(true); 355a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette outerOpacityAnim.setDuration(inflectionDuration); 3566ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setInterpolator(LINEAR_INTERPOLATOR); 3576ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3586ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette // Chain the outer opacity exit animation. 359a3f0c2b21a73a82a919abe247c4046d114f3712cAlan Viverette final int outerDuration = opacityDuration - inflectionDuration; 3606ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (outerDuration > 0) { 3616ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.addListener(new AnimatorListenerAdapter() { 3626ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette @Override 3636ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void onAnimationEnd(Animator animation) { 3646ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final ObjectAnimator outerFadeOutAnim = ObjectAnimator.ofFloat( 3656ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette RippleBackground.this, "outerOpacity", 0); 3666ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setAutoCancel(true); 3676ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setDuration(outerDuration); 3686ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.setInterpolator(LINEAR_INTERPOLATOR); 3696ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.addListener(mAnimationListener); 3706ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3716ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mAnimOuterOpacity = outerFadeOutAnim; 3726ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3736ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerFadeOutAnim.start(); 3746ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3756ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3766ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette @Override 3776ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void onAnimationCancel(Animator animation) { 3786ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette animation.removeListener(this); 3796ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3806ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette }); 3816ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 3826ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.addListener(mAnimationListener); 3836ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3846ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } else { 3856ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim = ObjectAnimator.ofFloat(this, "outerOpacity", 0); 3866ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setAutoCancel(true); 3876ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.setDuration(opacityDuration); 3886ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.addListener(mAnimationListener); 3896ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3906ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3916ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mAnimOuterOpacity = outerOpacityAnim; 3926ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3936ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette outerOpacityAnim.start(); 3946ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 3956ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 3966ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 397fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette * Cancel all animations. The caller is responsible for removing 398fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette * the ripple from the list of animating ripples. 3996ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 4006ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void cancel() { 4016ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette cancelSoftwareAnimations(); 4029bc11ac168d63900589158074028e6c480579421Alan Viverette cancelHardwareAnimations(false); 4036ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4046ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 4056ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private void cancelSoftwareAnimations() { 4066ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette if (mAnimOuterOpacity != null) { 4076ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mAnimOuterOpacity.cancel(); 408a2362c9251af9d27506aa12f49da42e019665555Alan Viverette mAnimOuterOpacity = null; 4096ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4106ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4116ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 4126ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette /** 4136ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette * Cancels any running hardware animations. 4146ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette */ 4159bc11ac168d63900589158074028e6c480579421Alan Viverette private void cancelHardwareAnimations(boolean jumpToEnd) { 4166ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations; 4176ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette final int N = runningAnimations.size(); 4186ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette for (int i = 0; i < N; i++) { 4199bc11ac168d63900589158074028e6c480579421Alan Viverette if (jumpToEnd) { 4209bc11ac168d63900589158074028e6c480579421Alan Viverette runningAnimations.get(i).end(); 4219bc11ac168d63900589158074028e6c480579421Alan Viverette } else { 4229bc11ac168d63900589158074028e6c480579421Alan Viverette runningAnimations.get(i).cancel(); 4239bc11ac168d63900589158074028e6c480579421Alan Viverette } 4246ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4256ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette runningAnimations.clear(); 426d78a44576c6bac5541e04c1f38599d43c9943653Alan Viverette 4279bc11ac168d63900589158074028e6c480579421Alan Viverette if (mHasPendingHardwareExit) { 4289bc11ac168d63900589158074028e6c480579421Alan Viverette // If we had a pending hardware exit, jump to the end state. 4299bc11ac168d63900589158074028e6c480579421Alan Viverette mHasPendingHardwareExit = false; 4309bc11ac168d63900589158074028e6c480579421Alan Viverette 4319bc11ac168d63900589158074028e6c480579421Alan Viverette if (jumpToEnd) { 4329bc11ac168d63900589158074028e6c480579421Alan Viverette mOuterOpacity = 0; 4339bc11ac168d63900589158074028e6c480579421Alan Viverette } 4349bc11ac168d63900589158074028e6c480579421Alan Viverette } 4359bc11ac168d63900589158074028e6c480579421Alan Viverette 436fdbb98e56d4668c7bfa8de59c3c438c0cb69a535Alan Viverette mHardwareAnimating = false; 4376ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4386ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 4396ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private void invalidateSelf() { 4406ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette mOwner.invalidateSelf(); 4416ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4426ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette 4436ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette private final AnimatorListenerAdapter mAnimationListener = new AnimatorListenerAdapter() { 4446ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette @Override 4456ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette public void onAnimationEnd(Animator animation) { 446be0dd99bac781d1dd73cb67f33bcd931e3693af5Alan Viverette mHardwareAnimating = false; 4476ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette } 4486ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette }; 4496ce6d70f9c78f0197f1369246bf55a5f6b8d7ba4Alan Viverette} 450