AnimatedVectorDrawable.java revision 727cae197b123ef764a1f8fbe08a995b000d14c3
1e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui/* 2e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * Copyright (C) 2014 The Android Open Source Project 3e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * 4e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * in compliance with the License. You may obtain a copy of the License at 6e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * 7e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * http://www.apache.org/licenses/LICENSE-2.0 8e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * 9e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * Unless required by applicable law or agreed to in writing, software distributed under the License 10e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * or implied. See the License for the specific language governing permissions and limitations under 12e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * the License. 13e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui */ 14e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 15e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuipackage android.graphics.drawable; 16e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 17e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.animation.Animator; 18e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.animation.AnimatorInflater; 196e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viveretteimport android.animation.ValueAnimator; 2006cd7dce24876b54870f9ef3831237f8298773a9Alan Viveretteimport android.annotation.NonNull; 2106cd7dce24876b54870f9ef3831237f8298773a9Alan Viveretteimport android.content.res.ColorStateList; 22e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.content.res.Resources; 23e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.content.res.Resources.Theme; 24e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.content.res.TypedArray; 25e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.graphics.Canvas; 26e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.graphics.ColorFilter; 2706cd7dce24876b54870f9ef3831237f8298773a9Alan Viveretteimport android.graphics.Outline; 2806cd7dce24876b54870f9ef3831237f8298773a9Alan Viveretteimport android.graphics.PorterDuff; 29e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.graphics.Rect; 306f6578e81c1df207da47e2e1337382341f271206Chet Haaseimport android.util.ArrayMap; 31e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.AttributeSet; 32e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.Log; 33e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 34e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport com.android.internal.R; 35e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 36e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport org.xmlpull.v1.XmlPullParser; 37e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport org.xmlpull.v1.XmlPullParserException; 38e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 39e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport java.io.IOException; 40e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport java.util.ArrayList; 41e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 42e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui/** 437e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * This class uses {@link android.animation.ObjectAnimator} and 447e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * {@link android.animation.AnimatorSet} to animate the properties of a 457e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * {@link android.graphics.drawable.VectorDrawable} to create an animated drawable. 467e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <p> 477e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * AnimatedVectorDrawable are normally defined as 3 separate XML files. 487e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </p> 497e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <p> 507e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * First is the XML file for {@link android.graphics.drawable.VectorDrawable}. 517e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * Note that we allow the animation happen on the group's attributes and path's 527e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * attributes, which requires they are uniquely named in this xml file. Groups 537e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * and paths without animations do not need names. 547e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </p> 557e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file. 567e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <pre> 57a95c8abb366d9c39450513335f550b56da13b30aztenghui * <vector xmlns:android="http://schemas.android.com/apk/res/android" 58a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:height="64dp" 59a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:width="64dp" 60a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportHeight="600" 61a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportWidth="600" > 627e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <group 637e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:name="rotationGroup" 647e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:pivotX="300.0" 657e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:pivotY="300.0" 667e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:rotation="45.0" > 677e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <path 687e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:name="v" 69a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:fillColor="#000000" 707e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 717e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </group> 727e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </vector> 737e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </pre></li> 747e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <p> 757e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * Second is the AnimatedVectorDrawable's xml file, which defines the target 767e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * VectorDrawable, the target paths and groups to animate, the properties of the 777e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * path and group to animate and the animations defined as the ObjectAnimators 787e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * or AnimatorSets. 797e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </p> 807e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <li>Here is a simple AnimatedVectorDrawable defined in this avd.xml file. 817e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * Note how we use the names to refer to the groups and paths in the vectordrawable.xml. 827e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <pre> 837e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 847e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:drawable="@drawable/vectordrawable" > 857e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <target 867e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:name="rotationGroup" 877e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:animation="@anim/rotation" /> 887e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <target 897e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:name="v" 907e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:animation="@anim/path_morph" /> 917e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </animated-vector> 927e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </pre></li> 937e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <p> 947e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * Last is the Animator xml file, which is the same as a normal ObjectAnimator 957e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * or AnimatorSet. 967e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * To complete this example, here are the 2 animator files used in avd.xml: 977e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * rotation.xml and path_morph.xml. 987e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </p> 997e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <li>Here is the rotation.xml, which will rotate the target group for 360 degrees. 1007e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <pre> 1017e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <objectAnimator 1027e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:duration="6000" 1037e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:propertyName="rotation" 1047e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:valueFrom="0" 1057e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:valueTo="360" /> 1067e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </pre></li> 1077e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <li>Here is the path_morph.xml, which will morph the path from one shape to 1087e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * the other. Note that the paths must be compatible for morphing. 1097e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * In more details, the paths should have exact same length of commands , and 1107e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * exact same length of parameters for each commands. 1117e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * Note that the path string are better stored in strings.xml for reusing. 1127e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <pre> 1137e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <set xmlns:android="http://schemas.android.com/apk/res/android"> 1147e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * <objectAnimator 1157e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:duration="3000" 1167e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:propertyName="pathData" 1177e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" 1187e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" 1197e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * android:valueType="pathType"/> 1207e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </set> 1217e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * </pre></li> 122e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui * 1237e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * @attr ref android.R.styleable#AnimatedVectorDrawable_drawable 1247e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_name 1257e7ea9da6785a8345feffb754ddcb55b16cf69c9ztenghui * @attr ref android.R.styleable#AnimatedVectorDrawableTarget_animation 126e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui */ 127e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuipublic class AnimatedVectorDrawable extends Drawable implements Animatable { 128e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private static final String LOGTAG = AnimatedVectorDrawable.class.getSimpleName(); 129e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 130e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private static final String ANIMATED_VECTOR = "animated-vector"; 131e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private static final String TARGET = "target"; 132e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 133e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false; 134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1356f6578e81c1df207da47e2e1337382341f271206Chet Haase private AnimatedVectorDrawableState mAnimatedVectorState; 1366f6578e81c1df207da47e2e1337382341f271206Chet Haase 1376f6578e81c1df207da47e2e1337382341f271206Chet Haase private boolean mMutated; 138e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 139e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public AnimatedVectorDrawable() { 14098916d146afe2ff25a439603f7d9559e74a790caztenghui mAnimatedVectorState = new AnimatedVectorDrawableState(null); 141e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 143e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res, 144e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Theme theme) { 145e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState = new AnimatedVectorDrawableState(state); 146e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (theme != null && canApplyTheme()) { 147e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui applyTheme(theme); 148e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 149e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 150e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 151e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 1526f6578e81c1df207da47e2e1337382341f271206Chet Haase public Drawable mutate() { 1536f6578e81c1df207da47e2e1337382341f271206Chet Haase if (!mMutated && super.mutate() == this) { 1545004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette mAnimatedVectorState.mVectorDrawable.mutate(); 1556f6578e81c1df207da47e2e1337382341f271206Chet Haase mMutated = true; 1566f6578e81c1df207da47e2e1337382341f271206Chet Haase } 1576f6578e81c1df207da47e2e1337382341f271206Chet Haase return this; 1586f6578e81c1df207da47e2e1337382341f271206Chet Haase } 1596f6578e81c1df207da47e2e1337382341f271206Chet Haase 160727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 161727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 162727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 163727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 164727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 165727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mAnimatedVectorState.mVectorDrawable.clearMutated(); 166727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 167727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 168727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 1696f6578e81c1df207da47e2e1337382341f271206Chet Haase @Override 170e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public ConstantState getConstantState() { 17198916d146afe2ff25a439603f7d9559e74a790caztenghui mAnimatedVectorState.mChangingConfigurations = getChangingConfigurations(); 1726f6578e81c1df207da47e2e1337382341f271206Chet Haase return mAnimatedVectorState; 173e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 175e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 17698916d146afe2ff25a439603f7d9559e74a790caztenghui public int getChangingConfigurations() { 17798916d146afe2ff25a439603f7d9559e74a790caztenghui return super.getChangingConfigurations() | mAnimatedVectorState.mChangingConfigurations; 17898916d146afe2ff25a439603f7d9559e74a790caztenghui } 17998916d146afe2ff25a439603f7d9559e74a790caztenghui 18098916d146afe2ff25a439603f7d9559e74a790caztenghui @Override 181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void draw(Canvas canvas) { 182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState.mVectorDrawable.draw(canvas); 18314aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui if (isStarted()) { 184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui invalidateSelf(); 185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 188e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui protected void onBoundsChange(Rect bounds) { 190e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState.mVectorDrawable.setBounds(bounds); 191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 19406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette protected boolean onStateChange(int[] state) { 19506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette return mAnimatedVectorState.mVectorDrawable.setState(state); 19606cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 19706cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 19806cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 19906cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette protected boolean onLevelChange(int level) { 20006cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette return mAnimatedVectorState.mVectorDrawable.setLevel(level); 20106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 20206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 20306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mAnimatedVectorState.mVectorDrawable.getAlpha(); 206e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 207e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 208e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 209e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setAlpha(int alpha) { 210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState.mVectorDrawable.setAlpha(alpha); 211e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 213e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 214e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setColorFilter(ColorFilter colorFilter) { 215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState.mVectorDrawable.setColorFilter(colorFilter); 216e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 218e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 21906cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void setTintList(ColorStateList tint) { 22006cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setTintList(tint); 22106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 22206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 22306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 22406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void setHotspot(float x, float y) { 22506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setHotspot(x, y); 22606cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 22706cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 22806cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 22906cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void setHotspotBounds(int left, int top, int right, int bottom) { 23006cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setHotspotBounds(left, top, right, bottom); 23106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 23206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 23306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 23406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void setTintMode(PorterDuff.Mode tintMode) { 23506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode); 23606cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 23706cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 23806cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 23906cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public boolean setVisible(boolean visible, boolean restart) { 24006cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setVisible(visible, restart); 24106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette return super.setVisible(visible, restart); 24206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 24306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 24406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette /** {@hide} */ 24506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 24606cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void setLayoutDirection(int layoutDirection) { 24706cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.setLayoutDirection(layoutDirection); 24806cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 24906cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 25006cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 25106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public boolean isStateful() { 25206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette return mAnimatedVectorState.mVectorDrawable.isStateful(); 25306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 25406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 25506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 256e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getOpacity() { 257e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mAnimatedVectorState.mVectorDrawable.getOpacity(); 258e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 259e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 260e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 261e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getIntrinsicWidth() { 262e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mAnimatedVectorState.mVectorDrawable.getIntrinsicWidth(); 263e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 264e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 265e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 266e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getIntrinsicHeight() { 267e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mAnimatedVectorState.mVectorDrawable.getIntrinsicHeight(); 268e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 269e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 270e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 27106cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette public void getOutline(@NonNull Outline outline) { 27206cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette mAnimatedVectorState.mVectorDrawable.getOutline(outline); 27306cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette } 27406cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette 27506cd7dce24876b54870f9ef3831237f8298773a9Alan Viverette @Override 276e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 277e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui throws XmlPullParserException, IOException { 278e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 279e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int eventType = parser.getEventType(); 280fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float pathErrorScale = 1; 281e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui while (eventType != XmlPullParser.END_DOCUMENT) { 282e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (eventType == XmlPullParser.START_TAG) { 283e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final String tagName = parser.getName(); 284e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (ANIMATED_VECTOR.equals(tagName)) { 285e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 286e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui R.styleable.AnimatedVectorDrawable); 287e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int drawableRes = a.getResourceId( 288e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui R.styleable.AnimatedVectorDrawable_drawable, 0); 289e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (drawableRes != 0) { 290fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount VectorDrawable vectorDrawable = (VectorDrawable) res.getDrawable( 29155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui drawableRes, theme).mutate(); 292fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount vectorDrawable.setAllowCaching(false); 293fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount pathErrorScale = vectorDrawable.getPixelSize(); 294fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mAnimatedVectorState.mVectorDrawable = vectorDrawable; 295e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 296e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui a.recycle(); 297e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } else if (TARGET.equals(tagName)) { 298e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 299e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui R.styleable.AnimatedVectorDrawableTarget); 300e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final String target = a.getString( 301e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui R.styleable.AnimatedVectorDrawableTarget_name); 302e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 303e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int id = a.getResourceId( 304e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui R.styleable.AnimatedVectorDrawableTarget_animation, 0); 305e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (id != 0) { 306fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id, 307fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount pathErrorScale); 308e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui setupAnimatorsForTarget(target, objectAnimator); 309e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 310e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui a.recycle(); 311e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 312e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 313e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 314e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui eventType = parser.next(); 315e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 316e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 317e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 318e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 319e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public boolean canApplyTheme() { 320e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return super.canApplyTheme() || mAnimatedVectorState != null 3219cb5b4c2d93acb9d6f5e14167e265c328c487d6bztenghui && mAnimatedVectorState.mVectorDrawable != null 3229cb5b4c2d93acb9d6f5e14167e265c328c487d6bztenghui && mAnimatedVectorState.mVectorDrawable.canApplyTheme(); 323e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 324e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 325e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 326e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void applyTheme(Theme t) { 327e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui super.applyTheme(t); 328e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 329e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final VectorDrawable vectorDrawable = mAnimatedVectorState.mVectorDrawable; 330e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (vectorDrawable != null && vectorDrawable.canApplyTheme()) { 331e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui vectorDrawable.applyTheme(t); 332e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 333e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 334e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 335e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private static class AnimatedVectorDrawableState extends ConstantState { 336e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int mChangingConfigurations; 337e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui VectorDrawable mVectorDrawable; 338e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui ArrayList<Animator> mAnimators; 3396f6578e81c1df207da47e2e1337382341f271206Chet Haase ArrayMap<Animator, String> mTargetNameMap; 340e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 341e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy) { 342e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (copy != null) { 343e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mChangingConfigurations = copy.mChangingConfigurations; 3446f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVectorDrawable != null) { 3456f6578e81c1df207da47e2e1337382341f271206Chet Haase mVectorDrawable = (VectorDrawable) copy.mVectorDrawable.getConstantState().newDrawable(); 3466f6578e81c1df207da47e2e1337382341f271206Chet Haase mVectorDrawable.mutate(); 3476f6578e81c1df207da47e2e1337382341f271206Chet Haase mVectorDrawable.setAllowCaching(false); 3486f6578e81c1df207da47e2e1337382341f271206Chet Haase mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds()); 3496f6578e81c1df207da47e2e1337382341f271206Chet Haase } 3506f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mAnimators != null) { 3516f6578e81c1df207da47e2e1337382341f271206Chet Haase final int numAnimators = copy.mAnimators.size(); 3526f6578e81c1df207da47e2e1337382341f271206Chet Haase mAnimators = new ArrayList<Animator>(numAnimators); 3536f6578e81c1df207da47e2e1337382341f271206Chet Haase mTargetNameMap = new ArrayMap<Animator, String>(numAnimators); 3546f6578e81c1df207da47e2e1337382341f271206Chet Haase for (int i = 0; i < numAnimators; ++i) { 3556f6578e81c1df207da47e2e1337382341f271206Chet Haase Animator anim = copy.mAnimators.get(i); 3566f6578e81c1df207da47e2e1337382341f271206Chet Haase Animator animClone = anim.clone(); 3576f6578e81c1df207da47e2e1337382341f271206Chet Haase String targetName = copy.mTargetNameMap.get(anim); 3586f6578e81c1df207da47e2e1337382341f271206Chet Haase Object targetObject = mVectorDrawable.getTargetByName(targetName); 3596f6578e81c1df207da47e2e1337382341f271206Chet Haase animClone.setTarget(targetObject); 3606f6578e81c1df207da47e2e1337382341f271206Chet Haase mAnimators.add(animClone); 3616f6578e81c1df207da47e2e1337382341f271206Chet Haase mTargetNameMap.put(animClone, targetName); 3626f6578e81c1df207da47e2e1337382341f271206Chet Haase } 3636f6578e81c1df207da47e2e1337382341f271206Chet Haase } 36498916d146afe2ff25a439603f7d9559e74a790caztenghui } else { 36598916d146afe2ff25a439603f7d9559e74a790caztenghui mVectorDrawable = new VectorDrawable(); 366e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 367e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 368e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 369e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 370e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public Drawable newDrawable() { 371e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return new AnimatedVectorDrawable(this, null, null); 372e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 373e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 374e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 375e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public Drawable newDrawable(Resources res) { 376e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return new AnimatedVectorDrawable(this, res, null); 377e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 378e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 379e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 380e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public Drawable newDrawable(Resources res, Theme theme) { 381e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return new AnimatedVectorDrawable(this, res, theme); 382e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 383e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 384e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 385e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getChangingConfigurations() { 386e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mChangingConfigurations; 387e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 388e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 389e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 390e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private void setupAnimatorsForTarget(String name, Animator animator) { 391e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name); 392e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui animator.setTarget(target); 3936f6578e81c1df207da47e2e1337382341f271206Chet Haase if (mAnimatedVectorState.mAnimators == null) { 3946f6578e81c1df207da47e2e1337382341f271206Chet Haase mAnimatedVectorState.mAnimators = new ArrayList<Animator>(); 3956f6578e81c1df207da47e2e1337382341f271206Chet Haase mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>(); 3966f6578e81c1df207da47e2e1337382341f271206Chet Haase } 397e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mAnimatedVectorState.mAnimators.add(animator); 3986f6578e81c1df207da47e2e1337382341f271206Chet Haase mAnimatedVectorState.mTargetNameMap.put(animator, name); 399e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (DBG_ANIMATION_VECTOR_DRAWABLE) { 400e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Log.v(LOGTAG, "add animator for target " + name + " " + animator); 401e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 402e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 403e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 404e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 405e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public boolean isRunning() { 406e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 407e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final int size = animators.size(); 408e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui for (int i = 0; i < size; i++) { 409e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final Animator animator = animators.get(i); 410e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (animator.isRunning()) { 411e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return true; 412e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 413e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 414e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return false; 415e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 416e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 41714aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui private boolean isStarted() { 41814aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 41914aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui final int size = animators.size(); 42014aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui for (int i = 0; i < size; i++) { 42114aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui final Animator animator = animators.get(i); 42214aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui if (animator.isStarted()) { 42314aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui return true; 42414aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui } 42514aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui } 42614aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui return false; 42714aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui } 42814aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui 429e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 430e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void start() { 431e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 432e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final int size = animators.size(); 433e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui for (int i = 0; i < size; i++) { 434e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final Animator animator = animators.get(i); 43514aedd1fbf52f1b844064a15d583ccfbda6ce57dztenghui if (!animator.isStarted()) { 436e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui animator.start(); 437e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 438e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 439e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui invalidateSelf(); 440e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 441e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 442e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 443e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void stop() { 444e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 445e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final int size = animators.size(); 446e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui for (int i = 0; i < size; i++) { 447e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui final Animator animator = animators.get(i); 44806eaf193bde2f8455a3f957f1df4b1c328ac1432ztenghui animator.end(); 449e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 450e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 4516e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette 4526e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette /** 4536e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette * Reverses ongoing animations or starts pending animations in reverse. 4546e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette * <p> 4556e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette * NOTE: Only works of all animations are ValueAnimators. 4567bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui * @hide 4576e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette */ 4587bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui public void reverse() { 4596e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 4606e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette final int size = animators.size(); 4616e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette for (int i = 0; i < size; i++) { 4626e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette final Animator animator = animators.get(i); 4637bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui if (animator.canReverse()) { 4647bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui animator.reverse(); 4657bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui } else { 4667bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui Log.w(LOGTAG, "AnimatedVectorDrawable can't reverse()"); 4676e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette } 4686e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette } 4696e0a9fa6ed86e918bfed5310d2522b2c2a527ef0Alan Viverette } 4707bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui 4717bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui /** 4727bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui * @hide 4737bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui */ 4747bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui public boolean canReverse() { 4757bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators; 4767bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui final int size = animators.size(); 4777bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui for (int i = 0; i < size; i++) { 4787bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui final Animator animator = animators.get(i); 4797bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui if (!animator.canReverse()) { 4807bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui return false; 4817bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui } 4827bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui } 4837bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui return true; 4847bc6a3f023ca3e1dde91fc97b6036dee3ba538a2ztenghui } 485e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui} 486