14fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui/* 24fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Copyright (C) 2015 The Android Open Source Project 34fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 44fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 54fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * in compliance with the License. You may obtain a copy of the License at 64fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 74fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * http://www.apache.org/licenses/LICENSE-2.0 84fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 94fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Unless required by applicable law or agreed to in writing, software distributed under the License 104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * or implied. See the License for the specific language governing permissions and limitations under 124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * the License. 134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuipackage android.support.graphics.drawable; 164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.animation.Animator; 185a1089de6e705823009189c75c630c12d0350921ztenghuiimport android.animation.AnimatorListenerAdapter; 1909c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haaseimport android.animation.AnimatorSet; 2009c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haaseimport android.animation.ArgbEvaluator; 2109c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haaseimport android.animation.ObjectAnimator; 224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.Context; 234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.ColorStateList; 244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.Resources; 254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.Resources.Theme; 264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.TypedArray; 274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Canvas; 284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.ColorFilter; 29ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhuimport android.graphics.PorterDuff; 304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Rect; 314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.drawable.Animatable; 329f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.graphics.drawable.AnimatedVectorDrawable; 334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.drawable.Drawable; 349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.os.Build; 359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.support.annotation.DrawableRes; 364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.annotation.NonNull; 374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.annotation.Nullable; 38905bcd294a7351749c60382eab03aa0c679e08bbAlan Viveretteimport android.support.annotation.RequiresApi; 39ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhuimport android.support.v4.content.res.ResourcesCompat; 40b6086751979cb14740815502597e9fcfddb7054aztenghuiimport android.support.v4.content.res.TypedArrayUtils; 41ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhuimport android.support.v4.graphics.drawable.DrawableCompat; 424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.v4.util.ArrayMap; 434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.AttributeSet; 444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.Log; 454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.Xml; 4667b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu 474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport org.xmlpull.v1.XmlPullParser; 484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport org.xmlpull.v1.XmlPullParserException; 494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport java.io.IOException; 514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport java.util.ArrayList; 5209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haaseimport java.util.List; 534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui/** 555a1089de6e705823009189c75c630c12d0350921ztenghui * For API 24 and above, this class is delegating to the framework's {@link 565a1089de6e705823009189c75c630c12d0350921ztenghui * AnimatedVectorDrawable}. 5780e3ecf1aae0badd8056206db0614e9b9d1934b5Teng-Hui Zhu * For older API version, this class uses {@link android.animation.ObjectAnimator} and 584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * {@link android.animation.AnimatorSet} to animate the properties of a 592c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu * {@link VectorDrawableCompat} to create an animated drawable. 60791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <p/> 61b6086751979cb14740815502597e9fcfddb7054aztenghui * AnimatedVectorDrawableCompat are defined in the same XML format as 62b6086751979cb14740815502597e9fcfddb7054aztenghui * {@link AnimatedVectorDrawable}. 63791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <p/> 64791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * Here are all the animatable attributes in {@link VectorDrawableCompat}: 65791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <table border="2" align="center" cellpadding="5"> 66791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <thead> 67791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 68791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <th>Element Name</th> 69791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <th>Animatable attribute name</th> 70791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 71791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </thead> 72791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 73791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td><vector></td> 74791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>alpha</td> 75791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 76791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 77791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td rowspan="7"><group></td> 78791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>rotation</td> 79791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 80791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 81791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>pivotX</td> 82791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 83791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 84791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>pivotY</td> 85791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 86791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 87791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>scaleX</td> 88791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 89791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 90791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>scaleY</td> 91791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 92791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 93791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>translateX</td> 94791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 95791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 96791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>translateY</td> 97791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 98791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 99791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td rowspan="8"><path></td> 100791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>fillColor</td> 101791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 102791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 103b6086751979cb14740815502597e9fcfddb7054aztenghui * <td>pathData</td> 104b6086751979cb14740815502597e9fcfddb7054aztenghui * </tr> 105b6086751979cb14740815502597e9fcfddb7054aztenghui * <tr> 106791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>strokeColor</td> 107791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 108791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 109791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>strokeWidth</td> 110791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 111791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 112791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>strokeAlpha</td> 113791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 114791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 115791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>fillAlpha</td> 116791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 117791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 118791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>trimPathStart</td> 119791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 120791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <tr> 121791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <td>trimPathOffset</td> 122791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </tr> 123791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </table> 124791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <p/> 1257c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * You can always create a AnimatedVectorDrawableCompat object and use it as a Drawable by the Java 1267c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * API. In order to refer to AnimatedVectorDrawableCompat inside a XML file, you can use 1277c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * app:srcCompat attribute in AppCompat library's ImageButton or ImageView. 128791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <p/> 129b6086751979cb14740815502597e9fcfddb7054aztenghui * Note that the animation in AnimatedVectorDrawableCompat now can support the following features: 130791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <ul> 131791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <li>Path Morphing (PathType evaluator). This is used for morphing one path into another.</li> 132791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <li>Path Interpolation. This is used to defined a flexible interpolator (represented as a path) 133791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * instead of the system defined ones like LinearInterpolator.</li> 134791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * <li>Animating 2 values in one ObjectAnimator according to one path's X value and Y value. One 135d84741a4ec99535a61779590eaf35474a561707aztenghui * usage is moving one object in both X and Y dimensions along an path.</li> 136791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu * </ul> 1374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 138b6086751979cb14740815502597e9fcfddb7054aztenghui 1395a1089de6e705823009189c75c630c12d0350921ztenghuipublic class AnimatedVectorDrawableCompat extends VectorDrawableCommon 1405a1089de6e705823009189c75c630c12d0350921ztenghui implements Animatable2Compat { 1419f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private static final String LOGTAG = "AnimatedVDCompat"; 1424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String ANIMATED_VECTOR = "animated-vector"; 1444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String TARGET = "target"; 1454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false; 1474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private AnimatedVectorDrawableCompatState mAnimatedVectorState; 1494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private Context mContext; 1514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase private ArgbEvaluator mArgbEvaluator = null; 15309c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase 1549f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AnimatedVectorDrawableDelegateState mCachedConstantStateDelegate; 1559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 1565a1089de6e705823009189c75c630c12d0350921ztenghui // Use internal listener to support AVDC's callback. 1575a1089de6e705823009189c75c630c12d0350921ztenghui private Animator.AnimatorListener mAnimatorListener = null; 1585a1089de6e705823009189c75c630c12d0350921ztenghui 1595a1089de6e705823009189c75c630c12d0350921ztenghui // Use an array to keep track of multiple call back associated with one drawable. 1605a1089de6e705823009189c75c630c12d0350921ztenghui private ArrayList<Animatable2Compat.AnimationCallback> mAnimationCallbacks = null; 1615a1089de6e705823009189c75c630c12d0350921ztenghui 1625a1089de6e705823009189c75c630c12d0350921ztenghui 1638fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas AnimatedVectorDrawableCompat() { 1649f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu this(null, null, null); 1659f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 1669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 1679f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private AnimatedVectorDrawableCompat(@Nullable Context context) { 1684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui this(context, null, null); 1694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1719f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private AnimatedVectorDrawableCompat(@Nullable Context context, 1725a1089de6e705823009189c75c630c12d0350921ztenghui @Nullable AnimatedVectorDrawableCompatState state, 1735a1089de6e705823009189c75c630c12d0350921ztenghui @Nullable Resources res) { 1744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mContext = context; 1754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (state != null) { 1764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState = state; 1774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 1784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState = new AnimatedVectorDrawableCompatState(context, state, mCallback, 1792c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu res); 1804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 18395ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu /** 18495ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu * mutate() will be effective only if the getConstantState() is returning non-null. 18595ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu * Otherwise, it just return the current object without modification. 18695ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu */ 1874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 1884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable mutate() { 1899f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 1909f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.mutate(); 1914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 19295ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu // For older platforms that there is no delegated drawable, we just return this without 19395ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu // any modification here, and the getConstantState() will return null in this case. 19495ca36d130e15b543de9b749b13fd8fd3dac851eTeng-Hui Zhu return this; 1954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 1994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Create a AnimatedVectorDrawableCompat object. 2004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 2014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @param context the context for creating the animators. 2022c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu * @param resId the resource ID for AnimatedVectorDrawableCompat object. 2034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @return a new AnimatedVectorDrawableCompat or null if parsing error is found. 2044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 2054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Nullable 2064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public static AnimatedVectorDrawableCompat create(@NonNull Context context, 2075a1089de6e705823009189c75c630c12d0350921ztenghui @DrawableRes int resId) { 208c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu if (Build.VERSION.SDK_INT >= 24) { 2099f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final AnimatedVectorDrawableCompat drawable = new AnimatedVectorDrawableCompat(context); 210ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu drawable.mDelegateDrawable = ResourcesCompat.getDrawable(context.getResources(), resId, 211ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu context.getTheme()); 2129f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawable.mDelegateDrawable.setCallback(drawable.mCallback); 2132c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu drawable.mCachedConstantStateDelegate = new AnimatedVectorDrawableDelegateState( 2142c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu drawable.mDelegateDrawable.getConstantState()); 2159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawable; 2169f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Resources resources = context.getResources(); 2184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui try { 219905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintResourceType - Parse drawable as XML. 2204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final XmlPullParser parser = resources.getXml(resId); 2214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 2224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int type; 2234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui while ((type = parser.next()) != XmlPullParser.START_TAG 2244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && type != XmlPullParser.END_DOCUMENT) { 2254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Empty loop 2264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (type != XmlPullParser.START_TAG) { 2284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException("No start tag found"); 2294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 230bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes return createFromXmlInner(context, context.getResources(), parser, attrs, 231bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes context.getTheme()); 2324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } catch (XmlPullParserException e) { 2334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.e(LOGTAG, "parser error", e); 2344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } catch (IOException e) { 2354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.e(LOGTAG, "parser error", e); 2364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return null; 2384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2409f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu /** 241bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes * Create a AnimatedVectorDrawableCompat from inside an XML document using an optional 242bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes * {@link Theme}. Called on a parser positioned at a tag in an XML 243bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes * document, tries to create a Drawable from that tag. Returns {@code null} 244bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes * if the tag is not a valid drawable. 245bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes */ 246bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes public static AnimatedVectorDrawableCompat createFromXmlInner(Context context, Resources r, 247bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes XmlPullParser parser, AttributeSet attrs, Theme theme) 248bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes throws XmlPullParserException, IOException { 249bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes final AnimatedVectorDrawableCompat drawable = new AnimatedVectorDrawableCompat(context); 250bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes drawable.inflate(r, parser, attrs, theme); 251bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes return drawable; 252bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes } 253bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes 254bd3494de1d97206f366f52641a14b21eb06a7022Chris Banes /** 2559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * {@inheritDoc} 256c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu * <strong>Note</strong> that we don't support constant state when SDK < 24. 2579f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * Make sure you check the return value before using it. 2589f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu */ 2594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public ConstantState getConstantState() { 261905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette if (mDelegateDrawable != null && Build.VERSION.SDK_INT >= 24) { 2622c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return new AnimatedVectorDrawableDelegateState(mDelegateDrawable.getConstantState()); 2639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2649f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // We can't support constant state in older platform. 2659f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // We need Context to create the animator, and we can't save the context in the constant 2669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // state. 2679f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return null; 2684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getChangingConfigurations() { 2729f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 2739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getChangingConfigurations(); 2749f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return super.getChangingConfigurations() | mAnimatedVectorState.mChangingConfigurations; 2764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void draw(Canvas canvas) { 2809f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 2819f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.draw(canvas); 2829f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2839f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.draw(canvas); 2855a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimatedVectorState.mAnimatorSet.isStarted()) { 2864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 2874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui protected void onBoundsChange(Rect bounds) { 2929f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 2939f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.setBounds(bounds); 2949f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2959f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setBounds(bounds); 2974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui protected boolean onStateChange(int[] state) { 3019f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3029f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.setState(state); 3039f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.setState(state); 3054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui protected boolean onLevelChange(int level) { 3099f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3109f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.setLevel(level); 3119f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.setLevel(level); 3134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 3164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getAlpha() { 3179f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 318ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu return DrawableCompat.getAlpha(mDelegateDrawable); 3199f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.getAlpha(); 3214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3239f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 3244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setAlpha(int alpha) { 3259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3269f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.setAlpha(alpha); 3279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 3289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setAlpha(alpha); 3304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setColorFilter(ColorFilter colorFilter) { 3349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.setColorFilter(colorFilter); 3369f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 3379f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setColorFilter(colorFilter); 3394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 34115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 342ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu public void setTint(int tint) { 343ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu if (mDelegateDrawable != null) { 344ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTint(mDelegateDrawable, tint); 345ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu return; 346ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu } 347ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu 348ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu mAnimatedVectorState.mVectorDrawable.setTint(tint); 349ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu } 350ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu 35115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 3524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTintList(ColorStateList tint) { 3539f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 354ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTintList(mDelegateDrawable, tint); 3559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 3569f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 357ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu 3584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setTintList(tint); 3594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 36115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 362ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu public void setTintMode(PorterDuff.Mode tintMode) { 3639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 364ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTintMode(mDelegateDrawable, tintMode); 3659f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 3669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 367ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu 368ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode); 3694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean setVisible(boolean visible, boolean restart) { 3739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3749f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.setVisible(visible, restart); 3759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setVisible(visible, restart); 3774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return super.setVisible(visible, restart); 3784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean isStateful() { 3829f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3839f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.isStateful(); 3849f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.isStateful(); 3864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getOpacity() { 3909f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3919f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getOpacity(); 3929f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.getOpacity(); 3944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 39615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 3974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getIntrinsicWidth() { 3989f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3999f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getIntrinsicWidth(); 4009f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.getIntrinsicWidth(); 4024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 40415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 4054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getIntrinsicHeight() { 4069f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 4079f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getIntrinsicHeight(); 4089f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mAnimatedVectorState.mVectorDrawable.getIntrinsicHeight(); 4104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4120327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu @Override 4130327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu public boolean isAutoMirrored() { 4140327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu if (mDelegateDrawable != null) { 4150327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu return DrawableCompat.isAutoMirrored(mDelegateDrawable); 4160327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu } 4170327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu return mAnimatedVectorState.mVectorDrawable.isAutoMirrored(); 4180327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu } 4190327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu 4200327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu @Override 4210327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu public void setAutoMirrored(boolean mirrored) { 4220327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu if (mDelegateDrawable != null) { 423905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette DrawableCompat.setAutoMirrored(mDelegateDrawable, mirrored); 4240327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu return; 4250327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu } 4260327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu mAnimatedVectorState.mVectorDrawable.setAutoMirrored(mirrored); 4270327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu } 4280327a65adda49ea1f39440a3127836b41ff43084Teng-Hui Zhu 4299f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 4304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throws XmlPullParserException, IOException { 4329f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 433ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.inflate(mDelegateDrawable, res, parser, attrs, theme); 4349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 4359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int eventType = parser.getEventType(); 43767b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu final int innerDepth = parser.getDepth() + 1; 43867b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu 43967b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu // Parse everything until the end of the animated-vector element. 44067b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu while (eventType != XmlPullParser.END_DOCUMENT 44167b6c5f8b82d730f3d39287af5e98adbd77c6ebfDoris Liu && (parser.getDepth() >= innerDepth || eventType != XmlPullParser.END_TAG)) { 4424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (eventType == XmlPullParser.START_TAG) { 4434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final String tagName = parser.getName(); 4444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (DBG_ANIMATION_VECTOR_DRAWABLE) { 4454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.v(LOGTAG, "tagName is " + tagName); 4464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (ANIMATED_VECTOR.equals(tagName)) { 4484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final TypedArray a = 449b6086751979cb14740815502597e9fcfddb7054aztenghui TypedArrayUtils.obtainAttributes(res, theme, attrs, 450b6086751979cb14740815502597e9fcfddb7054aztenghui AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE); 4514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4529f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu int drawableRes = a.getResourceId( 453b6086751979cb14740815502597e9fcfddb7054aztenghui AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_DRAWABLE, 0); 4544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (DBG_ANIMATION_VECTOR_DRAWABLE) { 4554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.v(LOGTAG, "drawableRes is " + drawableRes); 4564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (drawableRes != 0) { 4584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(res, 4594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui drawableRes, theme); 4604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui vectorDrawable.setAllowCaching(false); 4614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui vectorDrawable.setCallback(mCallback); 4624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mAnimatedVectorState.mVectorDrawable != null) { 4634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable.setCallback(null); 4644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mVectorDrawable = vectorDrawable; 4664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 4684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (TARGET.equals(tagName)) { 4694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final TypedArray a = 4709f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu res.obtainAttributes(attrs, 471b6086751979cb14740815502597e9fcfddb7054aztenghui AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET); 4724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final String target = a.getString( 473b6086751979cb14740815502597e9fcfddb7054aztenghui AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_NAME); 4744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu int id = a.getResourceId( 476b6086751979cb14740815502597e9fcfddb7054aztenghui AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_ANIMATION, 477b6086751979cb14740815502597e9fcfddb7054aztenghui 0); 4784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (id != 0) { 4799f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mContext != null) { 480b6086751979cb14740815502597e9fcfddb7054aztenghui // There are some important features (like path morphing), added into 481b6086751979cb14740815502597e9fcfddb7054aztenghui // Animator code to support AVD at API 21. 482b6086751979cb14740815502597e9fcfddb7054aztenghui Animator objectAnimator = AnimatorInflaterCompat.loadAnimator( 483b6086751979cb14740815502597e9fcfddb7054aztenghui mContext, id); 4849f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu setupAnimatorsForTarget(target, objectAnimator); 4859f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } else { 486f83358389f0c4ea37a7e7d9e493857f99baf0440Chris Banes a.recycle(); 4879f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu throw new IllegalStateException("Context can't be null when inflating" + 4889f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu " animators"); 4899f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 4924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui eventType = parser.next(); 4954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4965a1089de6e705823009189c75c630c12d0350921ztenghui 4975a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatedVectorState.setupAnimatorSet(); 4984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 5014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs) 5024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throws XmlPullParserException, IOException { 5034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui inflate(res, parser, attrs, null); 5044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5069f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5079f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public void applyTheme(Theme t) { 5089f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 509ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.applyTheme(mDelegateDrawable, t); 5109f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 5119f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5129f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // TODO: support theming in older platform. 5139f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 5149f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 51615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 5174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canApplyTheme() { 5189f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 519ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu return DrawableCompat.canApplyTheme(mDelegateDrawable); 5209f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5219f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // TODO: support theming in older platform. 5224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 5234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu /** 5269f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * Constant state for delegating the creating drawable job. 5279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * Instead of creating a VectorDrawable, create a VectorDrawableCompat instance which contains 5289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * a delegated VectorDrawable instance. 5299f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu */ 530905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette @RequiresApi(24) 5319f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private static class AnimatedVectorDrawableDelegateState extends ConstantState { 5329f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private final ConstantState mDelegateState; 5339f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public AnimatedVectorDrawableDelegateState(ConstantState state) { 5359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateState = state; 5369f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5379f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5389f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5399f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable() { 5409f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AnimatedVectorDrawableCompat drawableCompat = 5419f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu new AnimatedVectorDrawableCompat(); 542ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu drawableCompat.mDelegateDrawable = mDelegateState.newDrawable(); 5439f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable.setCallback(drawableCompat.mCallback); 5449f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 5459f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5469f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5479f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5489f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable(Resources res) { 5499f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AnimatedVectorDrawableCompat drawableCompat = 5509f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu new AnimatedVectorDrawableCompat(); 551ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu drawableCompat.mDelegateDrawable = mDelegateState.newDrawable(res); 5529f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable.setCallback(drawableCompat.mCallback); 5539f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 5549f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5569f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5579f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable(Resources res, Theme theme) { 5589f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AnimatedVectorDrawableCompat drawableCompat = 5599f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu new AnimatedVectorDrawableCompat(); 560ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu drawableCompat.mDelegateDrawable = mDelegateState.newDrawable(res, theme); 5619f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable.setCallback(drawableCompat.mCallback); 5629f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 5639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5649f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5659f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public boolean canApplyTheme() { 5679f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateState.canApplyTheme(); 5689f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5699f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5709f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 5719f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public int getChangingConfigurations() { 5729f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateState.getChangingConfigurations(); 5739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5749f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 5759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 5764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class AnimatedVectorDrawableCompatState extends ConstantState { 5774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mChangingConfigurations; 5784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VectorDrawableCompat mVectorDrawable; 5795a1089de6e705823009189c75c630c12d0350921ztenghui // Combining the array of Animators into a single AnimatorSet to hook up listener easier. 5805a1089de6e705823009189c75c630c12d0350921ztenghui AnimatorSet mAnimatorSet; 5815a1089de6e705823009189c75c630c12d0350921ztenghui private ArrayList<Animator> mAnimators; 5824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ArrayMap<Animator, String> mTargetNameMap; 5834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public AnimatedVectorDrawableCompatState(Context context, 5854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui AnimatedVectorDrawableCompatState copy, Callback owner, Resources res) { 5864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy != null) { 5874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChangingConfigurations = copy.mChangingConfigurations; 5884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy.mVectorDrawable != null) { 5894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final ConstantState cs = copy.mVectorDrawable.getConstantState(); 5904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (res != null) { 5914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable = (VectorDrawableCompat) cs.newDrawable(res); 5924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 5934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable = (VectorDrawableCompat) cs.newDrawable(); 5944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable = (VectorDrawableCompat) mVectorDrawable.mutate(); 5964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable.setCallback(owner); 5974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds()); 5984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorDrawable.setAllowCaching(false); 5994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy.mAnimators != null) { 6014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final int numAnimators = copy.mAnimators.size(); 6024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimators = new ArrayList<Animator>(numAnimators); 6034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTargetNameMap = new ArrayMap<Animator, String>(numAnimators); 6044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui for (int i = 0; i < numAnimators; ++i) { 6054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Animator anim = copy.mAnimators.get(i); 6064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Animator animClone = anim.clone(); 6074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui String targetName = copy.mTargetNameMap.get(anim); 6084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object targetObject = mVectorDrawable.getTargetByName(targetName); 6094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui animClone.setTarget(targetObject); 6104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimators.add(animClone); 6114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTargetNameMap.put(animClone, targetName); 6124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6135a1089de6e705823009189c75c630c12d0350921ztenghui setupAnimatorSet(); 6144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 6194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable newDrawable() { 620c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu throw new IllegalStateException("No constant state support for SDK < 24."); 6214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 6244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable newDrawable(Resources res) { 625c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu throw new IllegalStateException("No constant state support for SDK < 24."); 6264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 6294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getChangingConfigurations() { 6304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mChangingConfigurations; 6314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6325a1089de6e705823009189c75c630c12d0350921ztenghui 6335a1089de6e705823009189c75c630c12d0350921ztenghui public void setupAnimatorSet() { 6345a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimatorSet == null) { 6355a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatorSet = new AnimatorSet(); 6365a1089de6e705823009189c75c630c12d0350921ztenghui } 6375a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatorSet.playTogether(mAnimators); 6385a1089de6e705823009189c75c630c12d0350921ztenghui } 6394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 64109c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase /** 64209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase * Utility function to fix color interpolation prior to Lollipop. Without this fix, colors 64309c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase * are evaluated as raw integers instead of as colors, which leads to artifacts during 64409c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase * fillColor animations. 64509c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase */ 64609c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase private void setupColorAnimator(Animator animator) { 64709c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if (animator instanceof AnimatorSet) { 64809c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase List<Animator> childAnimators = ((AnimatorSet) animator).getChildAnimations(); 64909c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if (childAnimators != null) { 65009c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase for (int i = 0; i < childAnimators.size(); ++i) { 65109c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase setupColorAnimator(childAnimators.get(i)); 65209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 65309c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 65409c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 65509c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if (animator instanceof ObjectAnimator) { 65609c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase ObjectAnimator objectAnim = (ObjectAnimator) animator; 65709c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase final String propertyName = objectAnim.getPropertyName(); 65809c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if ("fillColor".equals(propertyName) || "strokeColor".equals(propertyName)) { 65909c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if (mArgbEvaluator == null) { 66009c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase mArgbEvaluator = new ArgbEvaluator(); 66109c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 66209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase objectAnim.setEvaluator(mArgbEvaluator); 66309c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 66409c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 66509c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 66609c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase 6674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void setupAnimatorsForTarget(String name, Animator animator) { 6684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name); 6694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui animator.setTarget(target); 67009c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 67109c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase setupColorAnimator(animator); 67209c0d7d7f4955586306bd9cdcf34567396a0d545Chet Haase } 6734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mAnimatedVectorState.mAnimators == null) { 6744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mAnimators = new ArrayList<Animator>(); 6754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>(); 6764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mAnimators.add(animator); 6784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAnimatedVectorState.mTargetNameMap.put(animator, name); 6794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (DBG_ANIMATION_VECTOR_DRAWABLE) { 6804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.v(LOGTAG, "add animator for target " + name + " " + animator); 6814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 6854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean isRunning() { 6869f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 687905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 688968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhu return ((AnimatedVectorDrawable) mDelegateDrawable).isRunning(); 6899f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6905a1089de6e705823009189c75c630c12d0350921ztenghui return mAnimatedVectorState.mAnimatorSet.isRunning(); 6914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 6944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void start() { 6959f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 696905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 697968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhu ((AnimatedVectorDrawable) mDelegateDrawable).start(); 6989f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 6999f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // If any one of the animator has not ended, do nothing. 7015a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimatedVectorState.mAnimatorSet.isStarted()) { 7024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return; 7034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7045a1089de6e705823009189c75c630c12d0350921ztenghui // Otherwise, kick off animatorSet. 7055a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatedVectorState.mAnimatorSet.start(); 7064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 7074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 7104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void stop() { 7119f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 712905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 713968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhu ((AnimatedVectorDrawable) mDelegateDrawable).stop(); 7149f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 7159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7165a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatedVectorState.mAnimatorSet.end(); 7174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7198fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas final Callback mCallback = new Callback() { 7204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 7214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void invalidateDrawable(Drawable who) { 7224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 7234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 7264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void scheduleDrawable(Drawable who, Runnable what, long when) { 7274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui scheduleSelf(what, when); 7284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 7314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void unscheduleDrawable(Drawable who, Runnable what) { 7324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui unscheduleSelf(what); 7334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui }; 7355a1089de6e705823009189c75c630c12d0350921ztenghui 7365a1089de6e705823009189c75c630c12d0350921ztenghui /** 7375a1089de6e705823009189c75c630c12d0350921ztenghui * A helper function to unregister the Animatable2Compat callback from the platform's 7385a1089de6e705823009189c75c630c12d0350921ztenghui * Animatable2 callback, while keeping the internal array of callback up to date. 7395a1089de6e705823009189c75c630c12d0350921ztenghui */ 740905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette @RequiresApi(23) 7415a1089de6e705823009189c75c630c12d0350921ztenghui private static boolean unregisterPlatformCallback(AnimatedVectorDrawable dr, 7425a1089de6e705823009189c75c630c12d0350921ztenghui Animatable2Compat.AnimationCallback callback) { 7435a1089de6e705823009189c75c630c12d0350921ztenghui return dr.unregisterAnimationCallback(callback.getPlatformCallback()); 7445a1089de6e705823009189c75c630c12d0350921ztenghui } 7455a1089de6e705823009189c75c630c12d0350921ztenghui 7465a1089de6e705823009189c75c630c12d0350921ztenghui @Override 7475a1089de6e705823009189c75c630c12d0350921ztenghui public void registerAnimationCallback(@NonNull Animatable2Compat.AnimationCallback 7485a1089de6e705823009189c75c630c12d0350921ztenghui callback) { 7495a1089de6e705823009189c75c630c12d0350921ztenghui if (mDelegateDrawable != null) { 750905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 7515a1089de6e705823009189c75c630c12d0350921ztenghui registerPlatformCallback((AnimatedVectorDrawable) mDelegateDrawable, callback); 7525a1089de6e705823009189c75c630c12d0350921ztenghui return; 7535a1089de6e705823009189c75c630c12d0350921ztenghui } 7545a1089de6e705823009189c75c630c12d0350921ztenghui 7555a1089de6e705823009189c75c630c12d0350921ztenghui if (callback == null) { 7565a1089de6e705823009189c75c630c12d0350921ztenghui return; 7575a1089de6e705823009189c75c630c12d0350921ztenghui } 7585a1089de6e705823009189c75c630c12d0350921ztenghui 7595a1089de6e705823009189c75c630c12d0350921ztenghui // Add listener accordingly. 7605a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimationCallbacks == null) { 7615a1089de6e705823009189c75c630c12d0350921ztenghui mAnimationCallbacks = new ArrayList<>(); 7625a1089de6e705823009189c75c630c12d0350921ztenghui } 7635a1089de6e705823009189c75c630c12d0350921ztenghui 7645a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimationCallbacks.contains(callback)) { 7655a1089de6e705823009189c75c630c12d0350921ztenghui // If this call back is already in, then don't need to append another copy. 7665a1089de6e705823009189c75c630c12d0350921ztenghui return; 7675a1089de6e705823009189c75c630c12d0350921ztenghui } 7685a1089de6e705823009189c75c630c12d0350921ztenghui 7695a1089de6e705823009189c75c630c12d0350921ztenghui mAnimationCallbacks.add(callback); 7705a1089de6e705823009189c75c630c12d0350921ztenghui 7715a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimatorListener == null) { 7725a1089de6e705823009189c75c630c12d0350921ztenghui // Create a animator listener and trigger the callback events when listener is 7735a1089de6e705823009189c75c630c12d0350921ztenghui // triggered. 7745a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatorListener = new AnimatorListenerAdapter() { 7755a1089de6e705823009189c75c630c12d0350921ztenghui @Override 7765a1089de6e705823009189c75c630c12d0350921ztenghui public void onAnimationStart(Animator animation) { 7775a1089de6e705823009189c75c630c12d0350921ztenghui ArrayList<Animatable2Compat.AnimationCallback> tmpCallbacks = 7785a1089de6e705823009189c75c630c12d0350921ztenghui new ArrayList<>(mAnimationCallbacks); 7795a1089de6e705823009189c75c630c12d0350921ztenghui int size = tmpCallbacks.size(); 7805a1089de6e705823009189c75c630c12d0350921ztenghui for (int i = 0; i < size; i++) { 7815a1089de6e705823009189c75c630c12d0350921ztenghui tmpCallbacks.get(i).onAnimationStart(AnimatedVectorDrawableCompat.this); 7825a1089de6e705823009189c75c630c12d0350921ztenghui } 7835a1089de6e705823009189c75c630c12d0350921ztenghui } 7845a1089de6e705823009189c75c630c12d0350921ztenghui 7855a1089de6e705823009189c75c630c12d0350921ztenghui @Override 7865a1089de6e705823009189c75c630c12d0350921ztenghui public void onAnimationEnd(Animator animation) { 7875a1089de6e705823009189c75c630c12d0350921ztenghui ArrayList<Animatable2Compat.AnimationCallback> tmpCallbacks = 7885a1089de6e705823009189c75c630c12d0350921ztenghui new ArrayList<>(mAnimationCallbacks); 7895a1089de6e705823009189c75c630c12d0350921ztenghui int size = tmpCallbacks.size(); 7905a1089de6e705823009189c75c630c12d0350921ztenghui for (int i = 0; i < size; i++) { 7915a1089de6e705823009189c75c630c12d0350921ztenghui tmpCallbacks.get(i).onAnimationEnd(AnimatedVectorDrawableCompat.this); 7925a1089de6e705823009189c75c630c12d0350921ztenghui } 7935a1089de6e705823009189c75c630c12d0350921ztenghui } 7945a1089de6e705823009189c75c630c12d0350921ztenghui }; 7955a1089de6e705823009189c75c630c12d0350921ztenghui } 7965a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatedVectorState.mAnimatorSet.addListener(mAnimatorListener); 7975a1089de6e705823009189c75c630c12d0350921ztenghui } 7985a1089de6e705823009189c75c630c12d0350921ztenghui 7995a1089de6e705823009189c75c630c12d0350921ztenghui /** 8005a1089de6e705823009189c75c630c12d0350921ztenghui * A helper function to register the Animatable2Compat callback on the platform's Animatable2 8015a1089de6e705823009189c75c630c12d0350921ztenghui * callback. 8025a1089de6e705823009189c75c630c12d0350921ztenghui */ 803905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette @RequiresApi(23) 8045a1089de6e705823009189c75c630c12d0350921ztenghui private static void registerPlatformCallback(@NonNull AnimatedVectorDrawable avd, 8055a1089de6e705823009189c75c630c12d0350921ztenghui @NonNull final Animatable2Compat.AnimationCallback callback) { 8065a1089de6e705823009189c75c630c12d0350921ztenghui avd.registerAnimationCallback(callback.getPlatformCallback()); 8075a1089de6e705823009189c75c630c12d0350921ztenghui } 8085a1089de6e705823009189c75c630c12d0350921ztenghui 8095a1089de6e705823009189c75c630c12d0350921ztenghui /** 8105a1089de6e705823009189c75c630c12d0350921ztenghui * A helper function to clean up the animator listener in the mAnimatorSet. 8115a1089de6e705823009189c75c630c12d0350921ztenghui */ 8125a1089de6e705823009189c75c630c12d0350921ztenghui private void removeAnimatorSetListener() { 8135a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimatorListener != null) { 8145a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatedVectorState.mAnimatorSet.removeListener(mAnimatorListener); 8155a1089de6e705823009189c75c630c12d0350921ztenghui mAnimatorListener = null; 8165a1089de6e705823009189c75c630c12d0350921ztenghui } 8175a1089de6e705823009189c75c630c12d0350921ztenghui } 8185a1089de6e705823009189c75c630c12d0350921ztenghui 8195a1089de6e705823009189c75c630c12d0350921ztenghui @Override 8205a1089de6e705823009189c75c630c12d0350921ztenghui public boolean unregisterAnimationCallback( 8215a1089de6e705823009189c75c630c12d0350921ztenghui @NonNull Animatable2Compat.AnimationCallback callback) { 8225a1089de6e705823009189c75c630c12d0350921ztenghui if (mDelegateDrawable != null) { 823905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 8245a1089de6e705823009189c75c630c12d0350921ztenghui unregisterPlatformCallback((AnimatedVectorDrawable) mDelegateDrawable, callback); 8255a1089de6e705823009189c75c630c12d0350921ztenghui } 8265a1089de6e705823009189c75c630c12d0350921ztenghui 8275a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimationCallbacks == null || callback == null) { 8285a1089de6e705823009189c75c630c12d0350921ztenghui // Nothing to be removed. 8295a1089de6e705823009189c75c630c12d0350921ztenghui return false; 8305a1089de6e705823009189c75c630c12d0350921ztenghui } 8315a1089de6e705823009189c75c630c12d0350921ztenghui boolean removed = mAnimationCallbacks.remove(callback); 8325a1089de6e705823009189c75c630c12d0350921ztenghui 8335a1089de6e705823009189c75c630c12d0350921ztenghui // When the last call back unregistered, remove the listener accordingly. 8345a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimationCallbacks.size() == 0) { 8355a1089de6e705823009189c75c630c12d0350921ztenghui removeAnimatorSetListener(); 8365a1089de6e705823009189c75c630c12d0350921ztenghui } 8375a1089de6e705823009189c75c630c12d0350921ztenghui return removed; 8385a1089de6e705823009189c75c630c12d0350921ztenghui } 8395a1089de6e705823009189c75c630c12d0350921ztenghui 8405a1089de6e705823009189c75c630c12d0350921ztenghui @Override 8415a1089de6e705823009189c75c630c12d0350921ztenghui public void clearAnimationCallbacks() { 8425a1089de6e705823009189c75c630c12d0350921ztenghui if (mDelegateDrawable != null) { 843905bcd294a7351749c60382eab03aa0c679e08bbAlan Viverette //noinspection AndroidLintNewApi - Implicit when delegate is non-null. 8445a1089de6e705823009189c75c630c12d0350921ztenghui ((AnimatedVectorDrawable) mDelegateDrawable).clearAnimationCallbacks(); 8455a1089de6e705823009189c75c630c12d0350921ztenghui return; 8465a1089de6e705823009189c75c630c12d0350921ztenghui } 8475a1089de6e705823009189c75c630c12d0350921ztenghui removeAnimatorSetListener(); 8485a1089de6e705823009189c75c630c12d0350921ztenghui if (mAnimationCallbacks == null) { 8495a1089de6e705823009189c75c630c12d0350921ztenghui return; 8505a1089de6e705823009189c75c630c12d0350921ztenghui } 8515a1089de6e705823009189c75c630c12d0350921ztenghui 8525a1089de6e705823009189c75c630c12d0350921ztenghui mAnimationCallbacks.clear(); 8535a1089de6e705823009189c75c630c12d0350921ztenghui } 8545a1089de6e705823009189c75c630c12d0350921ztenghui 8555a1089de6e705823009189c75c630c12d0350921ztenghui /** 8565a1089de6e705823009189c75c630c12d0350921ztenghui * Utility function to register callback to Drawable, when the drawable is created from XML and 8575a1089de6e705823009189c75c630c12d0350921ztenghui * referred in Java code, e.g: ImageView.getDrawable(). 8585a1089de6e705823009189c75c630c12d0350921ztenghui * From API 24 on, the drawable is treated as an AnimatedVectorDrawable. 8595a1089de6e705823009189c75c630c12d0350921ztenghui * Otherwise, it is treated as AnimatedVectorDrawableCompat. 8605a1089de6e705823009189c75c630c12d0350921ztenghui */ 8615a1089de6e705823009189c75c630c12d0350921ztenghui public static void registerAnimationCallback(Drawable dr, 8625a1089de6e705823009189c75c630c12d0350921ztenghui Animatable2Compat.AnimationCallback callback) { 8635a1089de6e705823009189c75c630c12d0350921ztenghui if (dr == null || callback == null) { 8645a1089de6e705823009189c75c630c12d0350921ztenghui return; 8655a1089de6e705823009189c75c630c12d0350921ztenghui } 8665a1089de6e705823009189c75c630c12d0350921ztenghui if (!(dr instanceof Animatable)) { 8675a1089de6e705823009189c75c630c12d0350921ztenghui return; 8685a1089de6e705823009189c75c630c12d0350921ztenghui } 8695a1089de6e705823009189c75c630c12d0350921ztenghui 8705a1089de6e705823009189c75c630c12d0350921ztenghui if (Build.VERSION.SDK_INT >= 24) { 8715a1089de6e705823009189c75c630c12d0350921ztenghui registerPlatformCallback((AnimatedVectorDrawable) dr, callback); 8725a1089de6e705823009189c75c630c12d0350921ztenghui } else { 8735a1089de6e705823009189c75c630c12d0350921ztenghui ((AnimatedVectorDrawableCompat) dr).registerAnimationCallback(callback); 8745a1089de6e705823009189c75c630c12d0350921ztenghui } 8755a1089de6e705823009189c75c630c12d0350921ztenghui } 8765a1089de6e705823009189c75c630c12d0350921ztenghui 8775a1089de6e705823009189c75c630c12d0350921ztenghui /** 8785a1089de6e705823009189c75c630c12d0350921ztenghui * Utility function to unregister animation callback from Drawable, when the drawable is 8795a1089de6e705823009189c75c630c12d0350921ztenghui * created from XML and referred in Java code, e.g: ImageView.getDrawable(). 8805a1089de6e705823009189c75c630c12d0350921ztenghui * From API 24 on, the drawable is treated as an AnimatedVectorDrawable. 8815a1089de6e705823009189c75c630c12d0350921ztenghui * Otherwise, it is treated as AnimatedVectorDrawableCompat. 8825a1089de6e705823009189c75c630c12d0350921ztenghui */ 8835a1089de6e705823009189c75c630c12d0350921ztenghui public static boolean unregisterAnimationCallback(Drawable dr, 8845a1089de6e705823009189c75c630c12d0350921ztenghui Animatable2Compat.AnimationCallback callback) { 8855a1089de6e705823009189c75c630c12d0350921ztenghui if (dr == null || callback == null) { 8865a1089de6e705823009189c75c630c12d0350921ztenghui return false; 8875a1089de6e705823009189c75c630c12d0350921ztenghui } 8885a1089de6e705823009189c75c630c12d0350921ztenghui if (!(dr instanceof Animatable)) { 8895a1089de6e705823009189c75c630c12d0350921ztenghui return false; 8905a1089de6e705823009189c75c630c12d0350921ztenghui } 8915a1089de6e705823009189c75c630c12d0350921ztenghui 8925a1089de6e705823009189c75c630c12d0350921ztenghui if (Build.VERSION.SDK_INT >= 24) { 8935a1089de6e705823009189c75c630c12d0350921ztenghui return unregisterPlatformCallback((AnimatedVectorDrawable) dr, callback); 8945a1089de6e705823009189c75c630c12d0350921ztenghui } else { 8955a1089de6e705823009189c75c630c12d0350921ztenghui return ((AnimatedVectorDrawableCompat) dr).unregisterAnimationCallback(callback); 8965a1089de6e705823009189c75c630c12d0350921ztenghui } 8975a1089de6e705823009189c75c630c12d0350921ztenghui } 8985a1089de6e705823009189c75c630c12d0350921ztenghui 8995a1089de6e705823009189c75c630c12d0350921ztenghui /** 9005a1089de6e705823009189c75c630c12d0350921ztenghui * Utility function to clear animation callbacks from Drawable, when the drawable is 9015a1089de6e705823009189c75c630c12d0350921ztenghui * created from XML and referred in Java code, e.g: ImageView.getDrawable(). 9025a1089de6e705823009189c75c630c12d0350921ztenghui * From API 24 on, the drawable is treated as an AnimatedVectorDrawable. 9035a1089de6e705823009189c75c630c12d0350921ztenghui * Otherwise, it is treated as AnimatedVectorDrawableCompat. 9045a1089de6e705823009189c75c630c12d0350921ztenghui */ 9055a1089de6e705823009189c75c630c12d0350921ztenghui public static void clearAnimationCallbacks(Drawable dr) { 9065a1089de6e705823009189c75c630c12d0350921ztenghui if (dr == null || !(dr instanceof Animatable)) { 9075a1089de6e705823009189c75c630c12d0350921ztenghui return; 9085a1089de6e705823009189c75c630c12d0350921ztenghui } 9095a1089de6e705823009189c75c630c12d0350921ztenghui if (Build.VERSION.SDK_INT >= 24) { 9105a1089de6e705823009189c75c630c12d0350921ztenghui ((AnimatedVectorDrawable) dr).clearAnimationCallbacks(); 9115a1089de6e705823009189c75c630c12d0350921ztenghui } else { 9125a1089de6e705823009189c75c630c12d0350921ztenghui ((AnimatedVectorDrawableCompat) dr).clearAnimationCallbacks(); 9135a1089de6e705823009189c75c630c12d0350921ztenghui } 9145a1089de6e705823009189c75c630c12d0350921ztenghui 9155a1089de6e705823009189c75c630c12d0350921ztenghui } 9164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui} 917