117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase/*
217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Copyright (C) 2010 The Android Open Source Project
317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase *
417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Licensed under the Apache License, Version 2.0 (the "License");
517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * you may not use this file except in compliance with the License.
617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * You may obtain a copy of the License at
717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase *
817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase *      http://www.apache.org/licenses/LICENSE-2.0
917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase *
1017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Unless required by applicable law or agreed to in writing, software
1117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * distributed under the License is distributed on an "AS IS" BASIS,
1217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * See the License for the specific language governing permissions and
1417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * limitations under the License.
1517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */
1617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
1717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haasepackage android.animation;
1817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
1987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viveretteimport android.annotation.NonNull;
2087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viveretteimport android.annotation.Nullable;
21c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mountimport android.graphics.Path;
22c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mountimport android.graphics.PointF;
2317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haaseimport android.util.Log;
24b39f051631250c49936a475d0e64584afb7f1b93Chet Haaseimport android.util.Property;
2517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
2687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viveretteimport java.lang.ref.WeakReference;
27e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haaseimport java.util.ArrayList;
2817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
2917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase/**
30a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * This subclass of {@link ValueAnimator} provides support for animating properties on target objects.
3117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * The constructors of this class take parameters to define the target object that will be animated
3217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * as well as the name of the property that will be animated. Appropriate set/get functions
3317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * are then determined internally and the animation will call these functions as necessary to
3417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animate the property.
356e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase *
363aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference">
373aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3>
383aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about animating with {@code ObjectAnimator}, read the
393aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/graphics/prop-animation.html#object-animator">Property
403aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * Animation</a> developer guide.</p>
413aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div>
423aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez *
436e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * @see #setPropertyName(String)
446e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase *
4517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */
462794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haasepublic final class ObjectAnimator extends ValueAnimator {
4787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    private static final String LOG_TAG = "ObjectAnimator";
4887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette
49e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase    private static final boolean DBG = false;
5017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
5187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    /**
5287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette     * A weak reference to the target object on which the property exists, set
5387ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette     * in the constructor. We'll cancel the animation if this goes away.
5487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette     */
5587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    private WeakReference<Object> mTarget;
5617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
5717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    private String mPropertyName;
5817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
59b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    private Property mProperty;
60b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
61be19e030a14c8e398e8af97fa898ea80187704dfChet Haase    private boolean mAutoCancel = false;
62be19e030a14c8e398e8af97fa898ea80187704dfChet Haase
6317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    /**
6417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * Sets the name of the property that will be animated. This name is used to derive
6517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * a setter function that will be called to set animated values.
6617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * For example, a property name of <code>foo</code> will result
6717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * in a call to the function <code>setFoo()</code> on the target object. If either
6817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
6917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * also be derived and called.
7017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
716e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * <p>For best performance of the mechanism that calls the setter function determined by the
726e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * name of the property being animated, use <code>float</code> or <code>int</code> typed values,
736e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * and make the setter function for those properties have a <code>void</code> return value. This
746e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * will cause the code to take an optimized path for these constrained circumstances. Other
756e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * property types and return types will work, but will have more overhead in processing
766e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     * the requests due to normal reflection mechanisms.</p>
776e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase     *
7817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * <p>Note that the setter function derived from this property name
7917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * must take the same parameter type as the
8017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
8117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * the setter function will fail.</p>
8217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
83a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase     * <p>If this ObjectAnimator has been set up to animate several properties together,
84d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase     * using more than one PropertyValuesHolder objects, then setting the propertyName simply
85d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase     * sets the propertyName in the first of those PropertyValuesHolder objects.</p>
86d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase     *
87b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param propertyName The name of the property being animated. Should not be null.
8817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     */
8987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    public void setPropertyName(@NonNull String propertyName) {
900e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase        // mValues could be null if this is being constructed piecemeal. Just record the
910e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase        // propertyName to be used later when setValues() is called if so.
92d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase        if (mValues != null) {
93602e4d3824bf8b9cb9f817375d195b969712176aChet Haase            PropertyValuesHolder valuesHolder = mValues[0];
94602e4d3824bf8b9cb9f817375d195b969712176aChet Haase            String oldName = valuesHolder.getPropertyName();
95d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase            valuesHolder.setPropertyName(propertyName);
96602e4d3824bf8b9cb9f817375d195b969712176aChet Haase            mValuesMap.remove(oldName);
97602e4d3824bf8b9cb9f817375d195b969712176aChet Haase            mValuesMap.put(propertyName, valuesHolder);
98d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase        }
9917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase        mPropertyName = propertyName;
1000e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase        // New property/values/target should cause re-initialization prior to starting
1010e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase        mInitialized = false;
10217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    }
10317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
10417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    /**
105b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Sets the property that will be animated. Property objects will take precedence over
106b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * properties specified by the {@link #setPropertyName(String)} method. Animations should
107b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * be set up to use one or the other, not both.
108b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     *
109b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param property The property being animated. Should not be null.
110b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     */
11187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    public void setProperty(@NonNull Property property) {
112b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        // mValues could be null if this is being constructed piecemeal. Just record the
113b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        // propertyName to be used later when setValues() is called if so.
114b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        if (mValues != null) {
115b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            PropertyValuesHolder valuesHolder = mValues[0];
116b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            String oldName = valuesHolder.getPropertyName();
117b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            valuesHolder.setProperty(property);
118b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            mValuesMap.remove(oldName);
119b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            mValuesMap.put(mPropertyName, valuesHolder);
120b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        }
121b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        if (mProperty != null) {
122b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            mPropertyName = property.getName();
123b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        }
124b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        mProperty = property;
125b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        // New property/values/target should cause re-initialization prior to starting
126b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        mInitialized = false;
127b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    }
128b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
129b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    /**
13017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * Gets the name of the property that will be animated. This name will be used to derive
13117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * a setter function that will be called to set animated values.
13217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * For example, a property name of <code>foo</code> will result
13317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * in a call to the function <code>setFoo()</code> on the target object. If either
13417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
13517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * also be derived and called.
136fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     *
137fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * <p>If this animator was created with a {@link Property} object instead of the
138fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * string name of a property, then this method will return the {@link
139fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * Property#getName() name} of that Property object instead. If this animator was
140fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * created with one or more {@link PropertyValuesHolder} objects, then this method
141fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * will return the {@link PropertyValuesHolder#getPropertyName() name} of that
142fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * object (if there was just one) or a comma-separated list of all of the
143fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase     * names (if there are more than one).</p>
14417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     */
14587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @Nullable
14617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    public String getPropertyName() {
147fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        String propertyName = null;
148fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        if (mPropertyName != null) {
149fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase            propertyName = mPropertyName;
150fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        } else if (mProperty != null) {
151fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase            propertyName = mProperty.getName();
152fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        } else if (mValues != null && mValues.length > 0) {
153fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase            for (int i = 0; i < mValues.length; ++i) {
154fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                if (i == 0) {
155fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                    propertyName = "";
156fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                } else {
157fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                    propertyName += ",";
158fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                }
159fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase                propertyName += mValues[i].getPropertyName();
160fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase            }
161fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        }
162fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        return propertyName;
163fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase    }
164fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase
165fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase    @Override
166fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase    String getNameForTrace() {
167fdd3ad7018ebb054c0288b8cd92739703a973181Chet Haase        return "animator:" + getPropertyName();
16817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    }
16917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
17017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    /**
171a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase     * Creates a new ObjectAnimator object. This default constructor is primarily for
172d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase     * use internally; the other constructors which take parameters are more generally
173d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase     * useful.
174d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase     */
175a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase    public ObjectAnimator() {
176d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase    }
177d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase
178d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase    /**
179b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Private utility constructor that initializes the target object and name of the
180b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * property being animated.
181fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase     *
18251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * @param target The object whose property is to be animated. This object should
18351ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * have a public method on it called <code>setName()</code>, where <code>name</code> is
18451ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * the value of the <code>propertyName</code> parameter.
185d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase     * @param propertyName The name of the property being animated.
186fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase     */
1872794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    private ObjectAnimator(Object target, String propertyName) {
18887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        setTarget(target);
189d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase        setPropertyName(propertyName);
190fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase    }
191fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase
192fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase    /**
193b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Private utility constructor that initializes the target object and property being animated.
194b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     *
195b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param target The object whose property is to be animated.
196b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param property The property being animated.
197b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     */
198b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    private <T> ObjectAnimator(T target, Property<T, ?> property) {
19987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        setTarget(target);
200b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        setProperty(property);
201b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    }
202b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
203b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    /**
2042794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * Constructs and returns an ObjectAnimator that animates between int values. A single
20516d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
206b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
207b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
208b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
2092794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     *
21051ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * @param target The object whose property is to be animated. This object should
21151ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * have a public method on it called <code>setName()</code>, where <code>name</code> is
21251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * the value of the <code>propertyName</code> parameter.
2132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param propertyName The name of the property being animated.
2142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param values A set of values that the animation will animate between over time.
215b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
2162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     */
2172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public static ObjectAnimator ofInt(Object target, String propertyName, int... values) {
2182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
2192794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        anim.setIntValues(values);
2202794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        return anim;
2212794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
2222794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
2232794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    /**
224c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
225c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
226c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
227c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are integers that are set to separate properties designated by
228c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>xPropertyName</code> and <code>yPropertyName</code>.
229c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
230c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose properties are to be animated. This object should
231c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               have public methods on it called <code>setNameX()</code> and
232c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
233c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               are the value of <code>xPropertyName</code> and <code>yPropertyName</code>
234c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               parameters, respectively.
235c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param xPropertyName The name of the property for the x coordinate being animated.
236c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param yPropertyName The name of the property for the y coordinate being animated.
237c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
238c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
239c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
240c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static ObjectAnimator ofInt(Object target, String xPropertyName, String yPropertyName,
241c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount            Path path) {
242984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PathKeyframes keyframes = KeyframeSet.ofPath(path);
243984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xPropertyName,
244984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createXIntKeyframes());
245984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yPropertyName,
246984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createYIntKeyframes());
247c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, x, y);
248c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
249c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
250c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
251b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Constructs and returns an ObjectAnimator that animates between int values. A single
25216d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
253b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
254b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
255b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
256b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     *
257b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param target The object whose property is to be animated.
258b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param property The property being animated.
259b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param values A set of values that the animation will animate between over time.
260b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
261b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     */
262b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> property, int... values) {
263b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, property);
264b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        anim.setIntValues(values);
265b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        return anim;
266b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    }
267b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
268b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    /**
269c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
270c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * using two properties.  A <code>Path</code></> animation moves in two dimensions, animating
271c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
272c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are integers that are set to separate properties, <code>xProperty</code> and
273c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>yProperty</code>.
274c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
275c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose properties are to be animated.
276c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param xProperty The property for the x coordinate being animated.
277c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param yProperty The property for the y coordinate being animated.
278c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
279c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
280c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
281c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> xProperty,
282c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount            Property<T, Integer> yProperty, Path path) {
283984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PathKeyframes keyframes = KeyframeSet.ofPath(path);
284984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xProperty,
285984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createXIntKeyframes());
286984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yProperty,
287984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createYIntKeyframes());
288c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, x, y);
289c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
290c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
291c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
2924eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Constructs and returns an ObjectAnimator that animates over int values for a multiple
2934eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * parameters setter. Only public methods that take only int parameters are supported.
2944eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Each <code>int[]</code> contains a complete set of parameters to the setter method.
2954eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * At least two <code>int[]</code> values must be provided, a start and end. More than two
2964eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * values imply a starting value, values to animate through along the way, and an ending
2974eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value (these values will be distributed evenly across the duration of the animation).
2984eed52944c0fcb3afa7369aba60fb5c655580286George Mount     *
2994eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param target The object whose property is to be animated. This object may
3004eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
3014eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
3024eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * be the case-sensitive complete name of the public setter method.
3034eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
3044eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param values A set of values that the animation will animate between over time.
3054eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
3064eed52944c0fcb3afa7369aba60fb5c655580286George Mount     */
3074eed52944c0fcb3afa7369aba60fb5c655580286George Mount    public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) {
3084eed52944c0fcb3afa7369aba60fb5c655580286George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values);
3094eed52944c0fcb3afa7369aba60fb5c655580286George Mount        return ofPropertyValuesHolder(target, pvh);
3104eed52944c0fcb3afa7369aba60fb5c655580286George Mount    }
3114eed52944c0fcb3afa7369aba60fb5c655580286George Mount
3124eed52944c0fcb3afa7369aba60fb5c655580286George Mount    /**
313c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates the target using a multi-int setter
314c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
315c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
316c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are integer x and y coordinates used in the first and second parameter of the
317c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * setter, respectively.
318c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
319c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose property is to be animated. This object may
320c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
321c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
322c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * be the case-sensitive complete name of the public setter method.
323c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
324c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
325c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
326c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
327c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static ObjectAnimator ofMultiInt(Object target, String propertyName, Path path) {
328c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, path);
329c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, pvh);
330c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
331c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
332c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
3334eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Constructs and returns an ObjectAnimator that animates over values for a multiple int
3344eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * parameters setter. Only public methods that take only int parameters are supported.
3354eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * <p>At least two values must be provided, a start and end. More than two
3364eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * values imply a starting value, values to animate through along the way, and an ending
3374eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value (these values will be distributed evenly across the duration of the animation).</p>
3384eed52944c0fcb3afa7369aba60fb5c655580286George Mount     *
3394eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param target The object whose property is to be animated. This object may
3404eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
3414eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
342c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * be the case-sensitive complete name of the public setter method.
3434eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
3444eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param converter Converts T objects into int parameters for the multi-value setter.
3454eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param evaluator A TypeEvaluator that will be called on each animation frame to
3464eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * provide the necessary interpolation between the Object values to derive the animated
3474eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value.
3484eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param values A set of values that the animation will animate between over time.
3494eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
3504eed52944c0fcb3afa7369aba60fb5c655580286George Mount     */
3514eed52944c0fcb3afa7369aba60fb5c655580286George Mount    public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName,
3524eed52944c0fcb3afa7369aba60fb5c655580286George Mount            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) {
3534eed52944c0fcb3afa7369aba60fb5c655580286George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter,
3544eed52944c0fcb3afa7369aba60fb5c655580286George Mount                evaluator, values);
3554eed52944c0fcb3afa7369aba60fb5c655580286George Mount        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
3564eed52944c0fcb3afa7369aba60fb5c655580286George Mount    }
3574eed52944c0fcb3afa7369aba60fb5c655580286George Mount
3584eed52944c0fcb3afa7369aba60fb5c655580286George Mount    /**
3591ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * Constructs and returns an ObjectAnimator that animates between color values. A single
3601ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * value implies that that value is the one being animated to. Two values imply starting
3611ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * and ending values. More than two values imply a starting value, values to animate through
3621ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * along the way, and an ending value (these values will be distributed evenly across
3631ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * the duration of the animation).
3641ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     *
3651ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param target The object whose property is to be animated. This object should
3661ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
3671ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * the value of the <code>propertyName</code> parameter.
3681ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param propertyName The name of the property being animated.
3691ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param values A set of values that the animation will animate between over time.
3701ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
3711ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     */
3721ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    public static ObjectAnimator ofArgb(Object target, String propertyName, int... values) {
3731ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        ObjectAnimator animator = ofInt(target, propertyName, values);
3741ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        animator.setEvaluator(ArgbEvaluator.getInstance());
3751ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        return animator;
3761ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    }
3771ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount
3781ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    /**
3791ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * Constructs and returns an ObjectAnimator that animates between color values. A single
3801ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * value implies that that value is the one being animated to. Two values imply starting
3811ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * and ending values. More than two values imply a starting value, values to animate through
3821ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * along the way, and an ending value (these values will be distributed evenly across
3831ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * the duration of the animation).
3841ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     *
3851ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param target The object whose property is to be animated.
3861ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param property The property being animated.
3871ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @param values A set of values that the animation will animate between over time.
3881ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
3891ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount     */
3901ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property,
3911ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount            int... values) {
3921ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        ObjectAnimator animator = ofInt(target, property, values);
3931ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        animator.setEvaluator(ArgbEvaluator.getInstance());
3941ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount        return animator;
3951ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    }
3961ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount
3971ffb280a7d2c70cc16d709c685f5d31fdb86b5e4George Mount    /**
3982794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * Constructs and returns an ObjectAnimator that animates between float values. A single
39916d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
400b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
401b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
402b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
4032794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     *
40451ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * @param target The object whose property is to be animated. This object should
40551ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * have a public method on it called <code>setName()</code>, where <code>name</code> is
40651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * the value of the <code>propertyName</code> parameter.
4072794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param propertyName The name of the property being animated.
4082794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param values A set of values that the animation will animate between over time.
409b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
4102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     */
4112794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
4122794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
4132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        anim.setFloatValues(values);
4142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        return anim;
4152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
4162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
4172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    /**
418c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
419c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
420c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
421c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are floats that are set to separate properties designated by
422c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>xPropertyName</code> and <code>yPropertyName</code>.
423c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
424c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose properties are to be animated. This object should
425c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               have public methods on it called <code>setNameX()</code> and
426c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
427c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               are the value of the <code>xPropertyName</code> and <code>yPropertyName</code>
428c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *               parameters, respectively.
429c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param xPropertyName The name of the property for the x coordinate being animated.
430c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param yPropertyName The name of the property for the y coordinate being animated.
431c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
432c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
433c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
434c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static ObjectAnimator ofFloat(Object target, String xPropertyName, String yPropertyName,
435c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount            Path path) {
436984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PathKeyframes keyframes = KeyframeSet.ofPath(path);
437984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xPropertyName,
438984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createXFloatKeyframes());
439984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yPropertyName,
440984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createYFloatKeyframes());
441c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, x, y);
442c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
443c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
444c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
445b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Constructs and returns an ObjectAnimator that animates between float values. A single
44616d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
447b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
448b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
449b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
450b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     *
451b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param target The object whose property is to be animated.
452b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param property The property being animated.
453b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param values A set of values that the animation will animate between over time.
454b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
455b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     */
456b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> property,
457b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            float... values) {
458b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, property);
459b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        anim.setFloatValues(values);
460b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        return anim;
461b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    }
462b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
463b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    /**
464c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
465c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
466c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
467c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are floats that are set to separate properties, <code>xProperty</code> and
468c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>yProperty</code>.
469c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
470c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose properties are to be animated.
471c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param xProperty The property for the x coordinate being animated.
472c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param yProperty The property for the y coordinate being animated.
473c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
474c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
475c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
476c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> xProperty,
477c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount            Property<T, Float> yProperty, Path path) {
478984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PathKeyframes keyframes = KeyframeSet.ofPath(path);
479984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframes(xProperty,
480984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createXFloatKeyframes());
481984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframes(yProperty,
482984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                keyframes.createYFloatKeyframes());
483f505b1f08d606688881d56591d018c0d9162d739George Mount        return ofPropertyValuesHolder(target, x, y);
484c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
485c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
486c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
4874eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Constructs and returns an ObjectAnimator that animates over float values for a multiple
4884eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * parameters setter. Only public methods that take only float parameters are supported.
4894eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Each <code>float[]</code> contains a complete set of parameters to the setter method.
4904eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * At least two <code>float[]</code> values must be provided, a start and end. More than two
4914eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * values imply a starting value, values to animate through along the way, and an ending
4924eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value (these values will be distributed evenly across the duration of the animation).
4934eed52944c0fcb3afa7369aba60fb5c655580286George Mount     *
4944eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param target The object whose property is to be animated. This object may
4954eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
4964eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
497c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * be the case-sensitive complete name of the public setter method.
4984eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
4994eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param values A set of values that the animation will animate between over time.
5004eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
5014eed52944c0fcb3afa7369aba60fb5c655580286George Mount     */
5024eed52944c0fcb3afa7369aba60fb5c655580286George Mount    public static ObjectAnimator ofMultiFloat(Object target, String propertyName,
5034eed52944c0fcb3afa7369aba60fb5c655580286George Mount            float[][] values) {
5044eed52944c0fcb3afa7369aba60fb5c655580286George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values);
5054eed52944c0fcb3afa7369aba60fb5c655580286George Mount        return ofPropertyValuesHolder(target, pvh);
5064eed52944c0fcb3afa7369aba60fb5c655580286George Mount    }
5074eed52944c0fcb3afa7369aba60fb5c655580286George Mount
5084eed52944c0fcb3afa7369aba60fb5c655580286George Mount    /**
509c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates the target using a multi-float setter
510c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
511c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
512c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * coordinates are float x and y coordinates used in the first and second parameter of the
513c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * setter, respectively.
514c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
515c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose property is to be animated. This object may
516c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
517c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
518c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * be the case-sensitive complete name of the public setter method.
519c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
520c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
521c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
522c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
523c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static ObjectAnimator ofMultiFloat(Object target, String propertyName, Path path) {
524c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, path);
525c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, pvh);
526c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
527c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
528c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
5294eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * Constructs and returns an ObjectAnimator that animates over values for a multiple float
5304eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * parameters setter. Only public methods that take only float parameters are supported.
5314eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * <p>At least two values must be provided, a start and end. More than two
5324eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * values imply a starting value, values to animate through along the way, and an ending
5334eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value (these values will be distributed evenly across the duration of the animation).</p>
5344eed52944c0fcb3afa7369aba60fb5c655580286George Mount     *
5354eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param target The object whose property is to be animated. This object may
5364eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
5374eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
5384eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * be the case-sensitive complete name of the public setter method.
5394eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param propertyName The name of the property being animated or the name of the setter method.
5404eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param converter Converts T objects into float parameters for the multi-value setter.
5414eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param evaluator A TypeEvaluator that will be called on each animation frame to
5424eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * provide the necessary interpolation between the Object values to derive the animated
5434eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * value.
5444eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @param values A set of values that the animation will animate between over time.
5454eed52944c0fcb3afa7369aba60fb5c655580286George Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
5464eed52944c0fcb3afa7369aba60fb5c655580286George Mount     */
5474eed52944c0fcb3afa7369aba60fb5c655580286George Mount    public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName,
5484eed52944c0fcb3afa7369aba60fb5c655580286George Mount            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) {
5494eed52944c0fcb3afa7369aba60fb5c655580286George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter,
5504eed52944c0fcb3afa7369aba60fb5c655580286George Mount                evaluator, values);
5514eed52944c0fcb3afa7369aba60fb5c655580286George Mount        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
5524eed52944c0fcb3afa7369aba60fb5c655580286George Mount    }
5534eed52944c0fcb3afa7369aba60fb5c655580286George Mount
5544eed52944c0fcb3afa7369aba60fb5c655580286George Mount    /**
555b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Constructs and returns an ObjectAnimator that animates between Object values. A single
55616d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
557b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
558b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
559b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
56017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
56151ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * @param target The object whose property is to be animated. This object should
562b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * have a public method on it called <code>setName()</code>, where <code>name</code> is
563b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the value of the <code>propertyName</code> parameter.
5642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param propertyName The name of the property being animated.
5652794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param evaluator A TypeEvaluator that will be called on each animation frame to
566b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * provide the necessary interpolation between the Object values to derive the animated
5672794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * value.
568b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param values A set of values that the animation will animate between over time.
569b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
570d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase     */
5712794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public static ObjectAnimator ofObject(Object target, String propertyName,
5722794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            TypeEvaluator evaluator, Object... values) {
5732794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
5742794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        anim.setObjectValues(values);
5752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        anim.setEvaluator(evaluator);
5762794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        return anim;
5772794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
5782794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
5792794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    /**
580c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
581c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
582c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
583c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * in a <code>PointF</code> to follow the <code>Path</code>. If the <code>Property</code>
584c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * associated with <code>propertyName</code> uses a type other than <code>PointF</code>,
585c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>converter</code> can be used to change from <code>PointF</code> to the type
586c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * associated with the <code>Property</code>.
587c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
588c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose property is to be animated. This object should
589c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * have a public method on it called <code>setName()</code>, where <code>name</code> is
590c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * the value of the <code>propertyName</code> parameter.
591c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param propertyName The name of the property being animated.
592c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param converter Converts a PointF to the type associated with the setter. May be
593c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *                  null if conversion is unnecessary.
594c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
595c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
596c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
59787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
598c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    public static ObjectAnimator ofObject(Object target, String propertyName,
59987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            @Nullable TypeConverter<PointF, ?> converter, Path path) {
600c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(propertyName, converter, path);
601c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, pvh);
602c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
603c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
604c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
605b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Constructs and returns an ObjectAnimator that animates between Object values. A single
60616d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
607b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * and ending values. More than two values imply a starting value, values to animate through
608b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * along the way, and an ending value (these values will be distributed evenly across
609b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the duration of the animation).
6102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     *
611b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param target The object whose property is to be animated.
612b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param property The property being animated.
613b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param evaluator A TypeEvaluator that will be called on each animation frame to
614b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * provide the necessary interpolation between the Object values to derive the animated
615b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * value.
616b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param values A set of values that the animation will animate between over time.
617b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
618b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     */
61987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
620b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
621b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            TypeEvaluator<V> evaluator, V... values) {
622b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        ObjectAnimator anim = new ObjectAnimator(target, property);
623b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        anim.setObjectValues(values);
624b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        anim.setEvaluator(evaluator);
625b39f051631250c49936a475d0e64584afb7f1b93Chet Haase        return anim;
626b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    }
627b39f051631250c49936a475d0e64584afb7f1b93Chet Haase
628b39f051631250c49936a475d0e64584afb7f1b93Chet Haase    /**
62916d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * Constructs and returns an ObjectAnimator that animates between Object values. A single
63016d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value implies that that value is the one being animated to. Two values imply starting
63116d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * and ending values. More than two values imply a starting value, values to animate through
63216d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * along the way, and an ending value (these values will be distributed evenly across
63316d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * the duration of the animation). This variant supplies a <code>TypeConverter</code> to
63416d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * convert from the animated values to the type of the property. If only one value is
63542516d19db936b10874c27e16eeacda041af01f9George Mount     * supplied, the <code>TypeConverter</code> must be a
63642516d19db936b10874c27e16eeacda041af01f9George Mount     * {@link android.animation.BidirectionalTypeConverter} to retrieve the current value.
63716d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     *
63816d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @param target The object whose property is to be animated.
63916d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @param property The property being animated.
64016d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @param converter Converts the animated object to the Property type.
64116d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @param evaluator A TypeEvaluator that will be called on each animation frame to
64216d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * provide the necessary interpolation between the Object values to derive the animated
64316d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * value.
64416d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @param values A set of values that the animation will animate between over time.
64516d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     * @return An ObjectAnimator object that is set up to animate between the given values.
64616d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount     */
64787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
64816d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount    public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
64916d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount            TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
65016d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
65116d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount                values);
65216d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount        return ofPropertyValuesHolder(target, pvh);
65316d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount    }
65416d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount
65516d2c9cc6bd67131d9921fbc14a69d88f48f48caGeorge Mount    /**
656c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
657c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
658c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
659c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * in a <code>PointF</code> to follow the <code>Path</code>. If <code>property</code>
660c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * uses a type other than <code>PointF</code>, <code>converter</code> can be used to change
661c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * from <code>PointF</code> to the type associated with the <code>Property</code>.
662c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *
663984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount     * <p>The PointF passed to <code>converter</code> or <code>property</code>, if
664984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount     * <code>converter</code> is <code>null</code>, is reused on each animation frame and should
665984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount     * not be stored by the setter or TypeConverter.</p>
666984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount     *
667c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param target The object whose property is to be animated.
668c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param property The property being animated. Should not be null.
669c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param converter Converts a PointF to the type associated with the setter. May be
670c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     *                  null if conversion is unnecessary.
671c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @param path The <code>Path</code> to animate values along.
672c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
673c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount     */
67487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
67587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    public static <T, V> ObjectAnimator ofObject(T target, @NonNull Property<T, V> property,
67687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            @Nullable TypeConverter<PointF, V> converter, Path path) {
677c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, path);
678c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount        return ofPropertyValuesHolder(target, pvh);
679c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    }
680c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount
681c96c7b2e54965e30c8fb82295f1ca9f891ebd5e7George Mount    /**
682b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * Constructs and returns an ObjectAnimator that animates between the sets of values specified
683b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * in <code>PropertyValueHolder</code> objects. This variant should be used when animating
684b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
685b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * you to associate a set of animation values with a property name.
686b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     *
687b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param target The object whose property is to be animated. Depending on how the
688b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * PropertyValuesObjects were constructed, the target object should either have the {@link
689b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the
690b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * PropertyValuesHOlder objects were created with property names) the target object should have
691b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * public methods on it called <code>setName()</code>, where <code>name</code> is the name of
692b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * the property passed in as the <code>propertyName</code> parameter for each of the
693b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * PropertyValuesHolder objects.
694b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @param values A set of PropertyValuesHolder objects whose values will be animated between
695b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * over time.
696b39f051631250c49936a475d0e64584afb7f1b93Chet Haase     * @return An ObjectAnimator object that is set up to animate between the given values.
6972794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     */
69887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
6992794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public static ObjectAnimator ofPropertyValuesHolder(Object target,
7002794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            PropertyValuesHolder... values) {
7012794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        ObjectAnimator anim = new ObjectAnimator();
70287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        anim.setTarget(target);
7032794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        anim.setValues(values);
7042794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        return anim;
7053dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase    }
7063dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase
70783d6e8213230fb0805aa019d266842253baeb114Romain Guy    @Override
7082794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public void setIntValues(int... values) {
70983d6e8213230fb0805aa019d266842253baeb114Romain Guy        if (mValues == null || mValues.length == 0) {
71083d6e8213230fb0805aa019d266842253baeb114Romain Guy            // No values yet - this animator is being constructed piecemeal. Init the values with
71183d6e8213230fb0805aa019d266842253baeb114Romain Guy            // whatever the current propertyName is
712b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            if (mProperty != null) {
713b39f051631250c49936a475d0e64584afb7f1b93Chet Haase                setValues(PropertyValuesHolder.ofInt(mProperty, values));
714b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            } else {
715b39f051631250c49936a475d0e64584afb7f1b93Chet Haase                setValues(PropertyValuesHolder.ofInt(mPropertyName, values));
716b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            }
71783d6e8213230fb0805aa019d266842253baeb114Romain Guy        } else {
7182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            super.setIntValues(values);
7192794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        }
7202794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
7212794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
7222794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    @Override
7232794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public void setFloatValues(float... values) {
7242794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        if (mValues == null || mValues.length == 0) {
7252794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            // No values yet - this animator is being constructed piecemeal. Init the values with
7262794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            // whatever the current propertyName is
727b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            if (mProperty != null) {
728b39f051631250c49936a475d0e64584afb7f1b93Chet Haase                setValues(PropertyValuesHolder.ofFloat(mProperty, values));
729b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            } else {
730b39f051631250c49936a475d0e64584afb7f1b93Chet Haase                setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
731b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            }
7322794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        } else {
7332794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            super.setFloatValues(values);
7342794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        }
7352794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
7362794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
7372794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    @Override
7382794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public void setObjectValues(Object... values) {
7392794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        if (mValues == null || mValues.length == 0) {
7402794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            // No values yet - this animator is being constructed piecemeal. Init the values with
7412794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            // whatever the current propertyName is
742b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            if (mProperty != null) {
743be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator) null, values));
744b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            } else {
745be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                setValues(PropertyValuesHolder.ofObject(mPropertyName,
746be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                        (TypeEvaluator) null, values));
747b39f051631250c49936a475d0e64584afb7f1b93Chet Haase            }
7482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        } else {
7492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase            super.setObjectValues(values);
75083d6e8213230fb0805aa019d266842253baeb114Romain Guy        }
7510e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase    }
75283d6e8213230fb0805aa019d266842253baeb114Romain Guy
753be19e030a14c8e398e8af97fa898ea80187704dfChet Haase    /**
754be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * autoCancel controls whether an ObjectAnimator will be canceled automatically
755be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * when any other ObjectAnimator with the same target and properties is started.
756be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * Setting this flag may make it easier to run different animators on the same target
757be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * object without having to keep track of whether there are conflicting animators that
758be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * need to be manually canceled. Canceling animators must have the same exact set of
759be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * target properties, in the same order.
760be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     *
761be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * @param cancel Whether future ObjectAnimators with the same target and properties
762be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     * as this ObjectAnimator will cause this ObjectAnimator to be canceled.
763be19e030a14c8e398e8af97fa898ea80187704dfChet Haase     */
764be19e030a14c8e398e8af97fa898ea80187704dfChet Haase    public void setAutoCancel(boolean cancel) {
765be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        mAutoCancel = cancel;
766be19e030a14c8e398e8af97fa898ea80187704dfChet Haase    }
767be19e030a14c8e398e8af97fa898ea80187704dfChet Haase
76887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    private boolean hasSameTargetAndProperties(@Nullable Animator anim) {
769be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        if (anim instanceof ObjectAnimator) {
770be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            PropertyValuesHolder[] theirValues = ((ObjectAnimator) anim).getValues();
77187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            if (((ObjectAnimator) anim).getTarget() == getTarget() &&
772be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    mValues.length == theirValues.length) {
773be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                for (int i = 0; i < mValues.length; ++i) {
774be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    PropertyValuesHolder pvhMine = mValues[i];
775be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    PropertyValuesHolder pvhTheirs = theirValues[i];
776be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    if (pvhMine.getPropertyName() == null ||
777be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                            !pvhMine.getPropertyName().equals(pvhTheirs.getPropertyName())) {
778be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                        return false;
779be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    }
780be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                }
781be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                return true;
782be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            }
783be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        }
784be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        return false;
785be19e030a14c8e398e8af97fa898ea80187704dfChet Haase    }
786be19e030a14c8e398e8af97fa898ea80187704dfChet Haase
787e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase    @Override
788e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase    public void start() {
789be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        // See if any of the current active/pending animators need to be canceled
790be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        AnimationHandler handler = sAnimationHandler.get();
791be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        if (handler != null) {
792be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            int numAnims = handler.mAnimations.size();
793be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            for (int i = numAnims - 1; i >= 0; i--) {
794be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                if (handler.mAnimations.get(i) instanceof ObjectAnimator) {
795be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    ObjectAnimator anim = (ObjectAnimator) handler.mAnimations.get(i);
796be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
797be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                        anim.cancel();
798be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    }
799be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                }
800be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            }
801be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            numAnims = handler.mPendingAnimations.size();
802be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            for (int i = numAnims - 1; i >= 0; i--) {
803be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                if (handler.mPendingAnimations.get(i) instanceof ObjectAnimator) {
804be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    ObjectAnimator anim = (ObjectAnimator) handler.mPendingAnimations.get(i);
805be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
806be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                        anim.cancel();
807be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    }
808be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                }
809be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            }
810be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            numAnims = handler.mDelayedAnims.size();
811be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            for (int i = numAnims - 1; i >= 0; i--) {
812be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                if (handler.mDelayedAnims.get(i) instanceof ObjectAnimator) {
813be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    ObjectAnimator anim = (ObjectAnimator) handler.mDelayedAnims.get(i);
814be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
815be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                        anim.cancel();
816be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                    }
817be19e030a14c8e398e8af97fa898ea80187704dfChet Haase                }
818be19e030a14c8e398e8af97fa898ea80187704dfChet Haase            }
819be19e030a14c8e398e8af97fa898ea80187704dfChet Haase        }
820e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase        if (DBG) {
82187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            Log.d(LOG_TAG, "Anim target, duration: " + getTarget() + ", " + getDuration());
822e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase            for (int i = 0; i < mValues.length; ++i) {
823e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase                PropertyValuesHolder pvh = mValues[i];
82487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                Log.d(LOG_TAG, "   Values[" + i + "]: " +
825984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                    pvh.getPropertyName() + ", " + pvh.mKeyframes.getValue(0) + ", " +
826984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount                    pvh.mKeyframes.getValue(1));
827e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase            }
828e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase        }
829e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase        super.start();
830e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase    }
831e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase
8323dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase    /**
83317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * This function is called immediately before processing the first animation
83417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * frame of an animation. If there is a nonzero <code>startDelay</code>, the
83517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * function is called after that delay ends.
83617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * It takes care of the final initialization steps for the
83717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * animation. This includes setting mEvaluator, if the user has not yet
83817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * set it up, and the setter/getter methods, if the user did not supply
83917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * them.
84017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
84117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *  <p>Overriders of this method should call the superclass method to cause
84217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *  internal mechanisms to be set up correctly.</p>
84317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     */
84417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    @Override
84517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    void initAnimation() {
84621cd1389d2ef218b20994b617c57af120841a57fChet Haase        if (!mInitialized) {
84721cd1389d2ef218b20994b617c57af120841a57fChet Haase            // mValueType may change due to setter/getter setup; do this before calling super.init(),
84821cd1389d2ef218b20994b617c57af120841a57fChet Haase            // which uses mValueType to set up the default type evaluator.
84987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            final Object target = getTarget();
85087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            if (target != null) {
85187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                final int numValues = mValues.length;
85287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                for (int i = 0; i < numValues; ++i) {
85387ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                    mValues[i].setupSetterAndGetter(target);
85487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                }
85521cd1389d2ef218b20994b617c57af120841a57fChet Haase            }
85621cd1389d2ef218b20994b617c57af120841a57fChet Haase            super.initAnimation();
85717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase        }
85817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    }
85917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
8602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    /**
8612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * Sets the length of the animation. The default duration is 300 milliseconds.
8622794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     *
8632794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @param duration The length of the animation, in milliseconds.
8642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * @return ObjectAnimator The object called with setDuration(). This return
8652794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * value makes it easier to compose statements together that construct and then set the
8662794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * duration, as in
8672794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>.
8682794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase     */
8692794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    @Override
87087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
8712794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    public ObjectAnimator setDuration(long duration) {
8722794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        super.setDuration(duration);
8732794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase        return this;
8742794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase    }
8752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase
87617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
87717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    /**
87817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * The target object whose property will be animated by this animation
87917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
88051ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy     * @return The object being animated
88117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     */
88287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @Nullable
88317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    public Object getTarget() {
88487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        return mTarget == null ? null : mTarget.get();
88517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    }
88617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase
88717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    /**
888e48ef2a3efedebdcc351b60d2f3c35c987811938George Mount     * Sets the target object whose property will be animated by this animation. If the
889e48ef2a3efedebdcc351b60d2f3c35c987811938George Mount     * animator has been started, it will be canceled.
890f54a8d7c479485174941c38f151ea7083c658da3Chet Haase     *
891f54a8d7c479485174941c38f151ea7083c658da3Chet Haase     * @param target The object being animated
892f54a8d7c479485174941c38f151ea7083c658da3Chet Haase     */
89321cd1389d2ef218b20994b617c57af120841a57fChet Haase    @Override
89487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    public void setTarget(@Nullable Object target) {
89587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        final Object oldTarget = getTarget();
89687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        if (oldTarget != target) {
897e48ef2a3efedebdcc351b60d2f3c35c987811938George Mount            if (isStarted()) {
898e48ef2a3efedebdcc351b60d2f3c35c987811938George Mount                cancel();
899e48ef2a3efedebdcc351b60d2f3c35c987811938George Mount            }
90087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            mTarget = target == null ? null : new WeakReference<Object>(target);
9018619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar            // New target should cause re-initialization prior to starting
90270d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase            mInitialized = false;
90370d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase        }
904f54a8d7c479485174941c38f151ea7083c658da3Chet Haase    }
905f54a8d7c479485174941c38f151ea7083c658da3Chet Haase
90621cd1389d2ef218b20994b617c57af120841a57fChet Haase    @Override
90721cd1389d2ef218b20994b617c57af120841a57fChet Haase    public void setupStartValues() {
90821cd1389d2ef218b20994b617c57af120841a57fChet Haase        initAnimation();
90987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette
91087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        final Object target = getTarget();
91187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        if (target != null) {
91287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            final int numValues = mValues.length;
91387ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            for (int i = 0; i < numValues; ++i) {
91487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                mValues[i].setupStartValue(target);
91587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            }
91621cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
91721cd1389d2ef218b20994b617c57af120841a57fChet Haase    }
91821cd1389d2ef218b20994b617c57af120841a57fChet Haase
91921cd1389d2ef218b20994b617c57af120841a57fChet Haase    @Override
92021cd1389d2ef218b20994b617c57af120841a57fChet Haase    public void setupEndValues() {
92121cd1389d2ef218b20994b617c57af120841a57fChet Haase        initAnimation();
92287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette
92387ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        final Object target = getTarget();
92487ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        if (target != null) {
92587ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            final int numValues = mValues.length;
92687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            for (int i = 0; i < numValues; ++i) {
92787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette                mValues[i].setupEndValue(target);
92887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            }
92921cd1389d2ef218b20994b617c57af120841a57fChet Haase        }
93021cd1389d2ef218b20994b617c57af120841a57fChet Haase    }
93121cd1389d2ef218b20994b617c57af120841a57fChet Haase
932f54a8d7c479485174941c38f151ea7083c658da3Chet Haase    /**
93317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * This method is called with the elapsed fraction of the animation during every
93417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * animation frame. This function turns the elapsed fraction into an interpolated fraction
93517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * and then into an animated value (from the evaluator. The function is called mostly during
93617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * animation updates, but it is also called when the <code>end()</code>
93717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * function is called, to set the final value on the property.
93817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
93917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * <p>Overrides of this method must call the superclass to perform the calculation
94017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * of the animated value.</p>
94117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     *
94217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     * @param fraction The elapsed fraction of the animation.
94317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase     */
94417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    @Override
94517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    void animateValue(float fraction) {
94687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        final Object target = getTarget();
94787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        if (mTarget != null && target == null) {
94887ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            // We lost the target reference, cancel and clean up.
94987ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            cancel();
95087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            return;
95187ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette        }
95287ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette
95317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase        super.animateValue(fraction);
954602e4d3824bf8b9cb9f817375d195b969712176aChet Haase        int numValues = mValues.length;
955602e4d3824bf8b9cb9f817375d195b969712176aChet Haase        for (int i = 0; i < numValues; ++i) {
95687ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            mValues[i].setAnimatedValue(target);
95717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase        }
95817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase    }
95949afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase
96049afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase    @Override
961a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase    public ObjectAnimator clone() {
962a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase        final ObjectAnimator anim = (ObjectAnimator) super.clone();
96349afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase        return anim;
96449afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase    }
965e9140a72b1059574046a624b471b2c3a35806496Chet Haase
966e9140a72b1059574046a624b471b2c3a35806496Chet Haase    @Override
96787ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette    @NonNull
968e9140a72b1059574046a624b471b2c3a35806496Chet Haase    public String toString() {
969e9140a72b1059574046a624b471b2c3a35806496Chet Haase        String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " +
97087ac5f60e20fba335497aa9dc03b7c29c4b966a2Alan Viverette            getTarget();
971e9140a72b1059574046a624b471b2c3a35806496Chet Haase        if (mValues != null) {
972e9140a72b1059574046a624b471b2c3a35806496Chet Haase            for (int i = 0; i < mValues.length; ++i) {
973e9140a72b1059574046a624b471b2c3a35806496Chet Haase                returnVal += "\n    " + mValues[i].toString();
974e9140a72b1059574046a624b471b2c3a35806496Chet Haase            }
975e9140a72b1059574046a624b471b2c3a35806496Chet Haase        }
976e9140a72b1059574046a624b471b2c3a35806496Chet Haase        return returnVal;
977e9140a72b1059574046a624b471b2c3a35806496Chet Haase    }
97817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase}
979