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>&lt;vector&gt;</td>
74791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu *         <td>alpha</td>
75791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu *     </tr>
76791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu *     <tr>
77791d564c66cf6bfc38413a35bf767b41cf019887Teng-Hui Zhu *         <td rowspan="7">&lt;group&gt;</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">&lt;path&gt;</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