ObjectAnimator.java revision 2794eb3b02e2404d453d3ad22a8a85a138130a07
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 1917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haaseimport android.util.Log; 2017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 2117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haaseimport java.lang.reflect.Method; 2217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 2317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase/** 24a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. 2517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * The constructors of this class take parameters to define the target object that will be animated 2617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * as well as the name of the property that will be animated. Appropriate set/get functions 2717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * are then determined internally and the animation will call these functions as necessary to 2817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animate the property. 2917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 302794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haasepublic final class ObjectAnimator extends ValueAnimator { 3117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase // The target object on which the property exists, set in the constructor 3317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase private Object mTarget; 3417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase private String mPropertyName; 3617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 3817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Sets the name of the property that will be animated. This name is used to derive 3917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * a setter function that will be called to set animated values. 4017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * For example, a property name of <code>foo</code> will result 4117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * in a call to the function <code>setFoo()</code> on the target object. If either 4217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 4317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * also be derived and called. 4417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 4517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Note that the setter function derived from this property name 4617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * must take the same parameter type as the 4717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to 4817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * the setter function will fail.</p> 4917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 50a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * <p>If this ObjectAnimator has been set up to animate several properties together, 51d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * using more than one PropertyValuesHolder objects, then setting the propertyName simply 52d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * sets the propertyName in the first of those PropertyValuesHolder objects.</p> 53d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * 5417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param propertyName The name of the property being animated. 5517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 5617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public void setPropertyName(String propertyName) { 570e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // mValues could be null if this is being constructed piecemeal. Just record the 580e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // propertyName to be used later when setValues() is called if so. 59d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase if (mValues != null) { 60602e4d3824bf8b9cb9f817375d195b969712176aChet Haase PropertyValuesHolder valuesHolder = mValues[0]; 61602e4d3824bf8b9cb9f817375d195b969712176aChet Haase String oldName = valuesHolder.getPropertyName(); 62d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase valuesHolder.setPropertyName(propertyName); 63602e4d3824bf8b9cb9f817375d195b969712176aChet Haase mValuesMap.remove(oldName); 64602e4d3824bf8b9cb9f817375d195b969712176aChet Haase mValuesMap.put(propertyName, valuesHolder); 65d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase } 6617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase mPropertyName = propertyName; 670e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // New property/values/target should cause re-initialization prior to starting 680e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase mInitialized = false; 6917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 7017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 7117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 7217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Gets the name of the property that will be animated. This name will be used to derive 7317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * a setter function that will be called to set animated values. 7417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * For example, a property name of <code>foo</code> will result 7517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * in a call to the function <code>setFoo()</code> on the target object. If either 7617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 7717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * also be derived and called. 7817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 7917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public String getPropertyName() { 8017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase return mPropertyName; 8117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 8217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 8317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 8417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Determine the setter or getter function using the JavaBeans convention of setFoo or 8517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * getFoo for a property named 'foo'. This function figures out what the name of the 8617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function should be and uses reflection to find the Method with that name on the 8717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * target object. 8817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 8917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param prefix "set" or "get", depending on whether we need a setter or getter. 9017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @return Method the method associated with mPropertyName. 9117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 92fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase private Method getPropertyFunction(String prefix, Class valueType) { 9317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase // TODO: faster implementation... 9417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase Method returnVal = null; 9517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String firstLetter = mPropertyName.substring(0, 1); 9617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String theRest = mPropertyName.substring(1); 9717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase firstLetter = firstLetter.toUpperCase(); 9817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String setterName = prefix + firstLetter + theRest; 99fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase Class args[] = null; 100fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase if (valueType != null) { 101fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase args = new Class[1]; 102fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase args[0] = valueType; 103fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase } 10417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase try { 10517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase returnVal = mTarget.getClass().getMethod(setterName, args); 10617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } catch (NoSuchMethodException e) { 107a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase Log.e("ObjectAnimator", 108fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase "Couldn't find setter/getter for property " + mPropertyName + ": " + e); 10917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 11017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase return returnVal; 11117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 11217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 11317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 114a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * Creates a new ObjectAnimator object. This default constructor is primarily for 115d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase * use internally; the other constructors which take parameters are more generally 116d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase * useful. 117d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase */ 118a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase public ObjectAnimator() { 119d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase } 120d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase 121d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase /** 122d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * A constructor that takes a single property name and set of values. This constructor is 123d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * used in the simple case of animating a single property. 124fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase * 125fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase * @param target The object whose property is to be animated. This object should 126d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * have a public method on it called <code>setName()</code>, where <code>name</code> is 127d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * the value of the <code>propertyName</code> parameter. 128d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * @param propertyName The name of the property being animated. 129fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase */ 1302794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase private ObjectAnimator(Object target, String propertyName) { 131fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase mTarget = target; 132d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase setPropertyName(propertyName); 133fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase } 134fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase 135fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase /** 1362794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between int values. A single 1372794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 1382794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 1392794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 1402794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 1412794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 1422794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 1432794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param target The object whose property is to be animated. This object should 1442794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * have a public method on it called <code>setName()</code>, where <code>name</code> is 1452794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * the value of the <code>propertyName</code> parameter. 1462794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 1472794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 1482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 1492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 1502794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { 1512794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 1522794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setIntValues(values); 1532794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 1542794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 1552794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 1562794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 1572794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between float values. A single 1582794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 1592794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 1602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 1612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 1622794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 1632794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 1642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param target The object whose property is to be animated. This object should 1652794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * have a public method on it called <code>setName()</code>, where <code>name</code> is 1662794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * the value of the <code>propertyName</code> parameter. 1672794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 1682794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 1692794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 1702794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 1712794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { 1722794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 1732794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setFloatValues(values); 1742794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 1752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 1762794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 1772794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 1782794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between long values. A single 1792794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 1802794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 1812794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 1822794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 1832794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 1842794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 1852794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param target The object whose property is to be animated. This object should 1862794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * have a public method on it called <code>setName()</code>, where <code>name</code> is 1872794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * the value of the <code>propertyName</code> parameter. 1882794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 1892794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 1902794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 1912794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 1922794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofLong(Object target, String propertyName, long... values) { 1932794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 1942794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setLongValues(values); 1952794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 1962794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 1972794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 1982794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 1992794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between double values. A single 2002794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 2012794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 2022794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 2032794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 2042794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 2052794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 2062794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param target The object whose property is to be animated. This object should 2072794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * have a public method on it called <code>setName()</code>, where <code>name</code> is 2082794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * the value of the <code>propertyName</code> parameter. 2092794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 2102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 2112794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 2122794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 2132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofDouble(Object target, String propertyName, double... values) { 2142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 2152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setDoubleValues(values); 2162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 2172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2192794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 220d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * A constructor that takes <code>PropertyValueHolder</code> values. This constructor should 221a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * be used when animating several properties at once with the same ObjectAnimator, since 222d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * PropertyValuesHolder allows you to associate a set of animation values with a property 223d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * name. 22417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 22517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param target The object whose property is to be animated. This object should 226d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * have public methods on it called <code>setName()</code>, where <code>name</code> is 227d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * the name of the property passed in as the <code>propertyName</code> parameter for 228d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * each of the PropertyValuesHolder objects. 2292794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 2302794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param evaluator A TypeEvaluator that will be called on each animation frame to 2312794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * provide the ncessry interpolation between the Object values to derive the animated 2322794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value. 233d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * @param values The PropertyValuesHolder objects which hold each the property name and values 234d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * to animate that property between. 235d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase */ 2362794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofObject(Object target, String propertyName, 2372794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase TypeEvaluator evaluator, Object... values) { 2382794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 2392794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setObjectValues(values); 2402794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setEvaluator(evaluator); 2412794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 2422794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2432794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2442794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 2452794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between the sets of values 2462794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * specifed in <code>PropertyValueHolder</code> objects. This variant should 2472794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be used when animating several properties at once with the same ObjectAnimator, since 2482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * PropertyValuesHolder allows you to associate a set of animation values with a property 2492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * name. 2502794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 2512794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param target The object whose property is to be animated. This object should 2522794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * have public methods on it called <code>setName()</code>, where <code>name</code> is 2532794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * the name of the property passed in as the <code>propertyName</code> parameter for 2542794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * each of the PropertyValuesHolder objects. 2552794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of PropertyValuesHolder objects whose values will be animated 2562794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * between over time. 2572794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 2582794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 2592794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofPropertyValuesHolder(Object target, 2602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase PropertyValuesHolder... values) { 2612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(); 2622794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.mTarget = target; 2632794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setValues(values); 2642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 2653dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase } 2663dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase 26783d6e8213230fb0805aa019d266842253baeb114Romain Guy @Override 2682794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setIntValues(int... values) { 26983d6e8213230fb0805aa019d266842253baeb114Romain Guy if (mValues == null || mValues.length == 0) { 27083d6e8213230fb0805aa019d266842253baeb114Romain Guy // No values yet - this animator is being constructed piecemeal. Init the values with 27183d6e8213230fb0805aa019d266842253baeb114Romain Guy // whatever the current propertyName is 2722794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); 27383d6e8213230fb0805aa019d266842253baeb114Romain Guy } else { 2742794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setIntValues(values); 2752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2762794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2772794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2782794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 2792794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setFloatValues(float... values) { 2802794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 2812794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 2822794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 2832794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); 2842794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 2852794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setFloatValues(values); 2862794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2872794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2882794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2892794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 2902794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setDoubleValues(double... values) { 2912794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 2922794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 2932794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 2942794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofDouble(mPropertyName, values)); 2952794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 2962794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setDoubleValues(values); 2972794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2982794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2992794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 3002794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 3012794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setLongValues(long... values) { 3022794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 3032794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 3042794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 3052794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofLong(mPropertyName, values)); 3062794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 3072794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setLongValues(values); 3082794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 3092794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 3102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 3112794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 3122794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setObjectValues(Object... values) { 3132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 3142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 3152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 3162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); 3172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 3182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setObjectValues(values); 31983d6e8213230fb0805aa019d266842253baeb114Romain Guy } 3200e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase } 32183d6e8213230fb0805aa019d266842253baeb114Romain Guy 3223dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase /** 32317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * This function is called immediately before processing the first animation 32417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * frame of an animation. If there is a nonzero <code>startDelay</code>, the 32517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function is called after that delay ends. 32617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * It takes care of the final initialization steps for the 32717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation. This includes setting mEvaluator, if the user has not yet 32817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * set it up, and the setter/getter methods, if the user did not supply 32917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * them. 33017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 33117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Overriders of this method should call the superclass method to cause 33217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * internal mechanisms to be set up correctly.</p> 33317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 33417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase @Override 33517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase void initAnimation() { 33621cd1389d2ef218b20994b617c57af120841a57fChet Haase if (!mInitialized) { 33721cd1389d2ef218b20994b617c57af120841a57fChet Haase // mValueType may change due to setter/getter setup; do this before calling super.init(), 33821cd1389d2ef218b20994b617c57af120841a57fChet Haase // which uses mValueType to set up the default type evaluator. 33921cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 34021cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 34121cd1389d2ef218b20994b617c57af120841a57fChet Haase mValues[i].setupSetterAndGetter(mTarget); 34221cd1389d2ef218b20994b617c57af120841a57fChet Haase } 34321cd1389d2ef218b20994b617c57af120841a57fChet Haase super.initAnimation(); 34417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 34517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 34617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3472794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 3482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Sets the length of the animation. The default duration is 300 milliseconds. 3492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 3502794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param duration The length of the animation, in milliseconds. 3512794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return ObjectAnimator The object called with setDuration(). This return 3522794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value makes it easier to compose statements together that construct and then set the 3532794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * duration, as in 3542794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>. 3552794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 3562794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 3572794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public ObjectAnimator setDuration(long duration) { 3582794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setDuration(duration); 3592794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return this; 3602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 3612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 36217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 36317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 36417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * The target object whose property will be animated by this animation 36517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 36617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @return The object being animated 36717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 36817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public Object getTarget() { 36917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase return mTarget; 37017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 37117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 37217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 373f54a8d7c479485174941c38f151ea7083c658da3Chet Haase * Sets the target object whose property will be animated by this animation 374f54a8d7c479485174941c38f151ea7083c658da3Chet Haase * 375f54a8d7c479485174941c38f151ea7083c658da3Chet Haase * @param target The object being animated 376f54a8d7c479485174941c38f151ea7083c658da3Chet Haase */ 37721cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 378f54a8d7c479485174941c38f151ea7083c658da3Chet Haase public void setTarget(Object target) { 379f54a8d7c479485174941c38f151ea7083c658da3Chet Haase mTarget = target; 3800e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // New property/values/target should cause re-initialization prior to starting 3810e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase mInitialized = false; 382f54a8d7c479485174941c38f151ea7083c658da3Chet Haase } 383f54a8d7c479485174941c38f151ea7083c658da3Chet Haase 38421cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 38521cd1389d2ef218b20994b617c57af120841a57fChet Haase public void setupStartValues() { 38621cd1389d2ef218b20994b617c57af120841a57fChet Haase initAnimation(); 38721cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 38821cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 38921cd1389d2ef218b20994b617c57af120841a57fChet Haase mValues[i].setupStartValue(mTarget); 39021cd1389d2ef218b20994b617c57af120841a57fChet Haase } 39121cd1389d2ef218b20994b617c57af120841a57fChet Haase } 39221cd1389d2ef218b20994b617c57af120841a57fChet Haase 39321cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 39421cd1389d2ef218b20994b617c57af120841a57fChet Haase public void setupEndValues() { 39521cd1389d2ef218b20994b617c57af120841a57fChet Haase initAnimation(); 39621cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 39721cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 39821cd1389d2ef218b20994b617c57af120841a57fChet Haase mValues[i].setupEndValue(mTarget); 39921cd1389d2ef218b20994b617c57af120841a57fChet Haase } 40021cd1389d2ef218b20994b617c57af120841a57fChet Haase } 40121cd1389d2ef218b20994b617c57af120841a57fChet Haase 402f54a8d7c479485174941c38f151ea7083c658da3Chet Haase /** 40317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * This method is called with the elapsed fraction of the animation during every 40417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation frame. This function turns the elapsed fraction into an interpolated fraction 40517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * and then into an animated value (from the evaluator. The function is called mostly during 40617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation updates, but it is also called when the <code>end()</code> 40717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function is called, to set the final value on the property. 40817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 40917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Overrides of this method must call the superclass to perform the calculation 41017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * of the animated value.</p> 41117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 41217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param fraction The elapsed fraction of the animation. 41317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 41417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase @Override 41517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase void animateValue(float fraction) { 41617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase super.animateValue(fraction); 417602e4d3824bf8b9cb9f817375d195b969712176aChet Haase int numValues = mValues.length; 418602e4d3824bf8b9cb9f817375d195b969712176aChet Haase for (int i = 0; i < numValues; ++i) { 419602e4d3824bf8b9cb9f817375d195b969712176aChet Haase mValues[i].setAnimatedValue(mTarget); 42017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 42117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 42249afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase 42349afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase @Override 424a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase public ObjectAnimator clone() { 425a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase final ObjectAnimator anim = (ObjectAnimator) super.clone(); 42649afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase return anim; 42749afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase } 42817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase} 429