ObjectAnimator.java revision 51ae5fc2d22a7bb616f432d7bac66bbbf8a1927f
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; 22e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haaseimport java.util.ArrayList; 2317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 2417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase/** 25a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. 2617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * The constructors of this class take parameters to define the target object that will be animated 2717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * as well as the name of the property that will be animated. Appropriate set/get functions 2817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * are then determined internally and the animation will call these functions as necessary to 2917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animate the property. 306e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * 316e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * @see #setPropertyName(String) 326e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * 3317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 342794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haasepublic final class ObjectAnimator extends ValueAnimator { 35e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase private static final boolean DBG = false; 3617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase // The target object on which the property exists, set in the constructor 3851ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy private Object mTarget; 3917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 4017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase private String mPropertyName; 4117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 4217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 4317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Sets the name of the property that will be animated. This name is used to derive 4417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * a setter function that will be called to set animated values. 4517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * For example, a property name of <code>foo</code> will result 4617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * in a call to the function <code>setFoo()</code> on the target object. If either 4717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 4817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * also be derived and called. 4917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 506e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * <p>For best performance of the mechanism that calls the setter function determined by the 516e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * name of the property being animated, use <code>float</code> or <code>int</code> typed values, 526e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * and make the setter function for those properties have a <code>void</code> return value. This 536e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * will cause the code to take an optimized path for these constrained circumstances. Other 546e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * property types and return types will work, but will have more overhead in processing 556e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * the requests due to normal reflection mechanisms.</p> 566e0ecb4eed5cd2e1f15766d7028467129974a12dChet Haase * 5717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Note that the setter function derived from this property name 5817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * must take the same parameter type as the 5917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to 6017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * the setter function will fail.</p> 6117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 62a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * <p>If this ObjectAnimator has been set up to animate several properties together, 63d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * using more than one PropertyValuesHolder objects, then setting the propertyName simply 64d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * sets the propertyName in the first of those PropertyValuesHolder objects.</p> 65d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * 6617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param propertyName The name of the property being animated. 6717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 6817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public void setPropertyName(String propertyName) { 690e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // mValues could be null if this is being constructed piecemeal. Just record the 700e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // propertyName to be used later when setValues() is called if so. 71d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase if (mValues != null) { 72602e4d3824bf8b9cb9f817375d195b969712176aChet Haase PropertyValuesHolder valuesHolder = mValues[0]; 73602e4d3824bf8b9cb9f817375d195b969712176aChet Haase String oldName = valuesHolder.getPropertyName(); 74d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase valuesHolder.setPropertyName(propertyName); 75602e4d3824bf8b9cb9f817375d195b969712176aChet Haase mValuesMap.remove(oldName); 76602e4d3824bf8b9cb9f817375d195b969712176aChet Haase mValuesMap.put(propertyName, valuesHolder); 77d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase } 7817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase mPropertyName = propertyName; 790e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase // New property/values/target should cause re-initialization prior to starting 800e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase mInitialized = false; 8117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 8217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 8317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 8417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Gets the name of the property that will be animated. This name will be used to derive 8517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * a setter function that will be called to set animated values. 8617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * For example, a property name of <code>foo</code> will result 8717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * in a call to the function <code>setFoo()</code> on the target object. If either 8817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 8917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * also be derived and called. 9017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 9117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public String getPropertyName() { 9217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase return mPropertyName; 9317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 9417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 9517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 9617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * Determine the setter or getter function using the JavaBeans convention of setFoo or 9717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * getFoo for a property named 'foo'. This function figures out what the name of the 9817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function should be and uses reflection to find the Method with that name on the 9917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * target object. 10017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 10117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param prefix "set" or "get", depending on whether we need a setter or getter. 10217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @return Method the method associated with mPropertyName. 10317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 104fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase private Method getPropertyFunction(String prefix, Class valueType) { 10517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase // TODO: faster implementation... 10617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase Method returnVal = null; 10717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String firstLetter = mPropertyName.substring(0, 1); 10817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String theRest = mPropertyName.substring(1); 10917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase firstLetter = firstLetter.toUpperCase(); 11017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase String setterName = prefix + firstLetter + theRest; 111fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase Class args[] = null; 112fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase if (valueType != null) { 113fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase args = new Class[1]; 114fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase args[0] = valueType; 115fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase } 11617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase try { 11751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy returnVal = mTarget.getClass().getMethod(setterName, args); 11817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } catch (NoSuchMethodException e) { 119a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase Log.e("ObjectAnimator", 120fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase "Couldn't find setter/getter for property " + mPropertyName + ": " + e); 12117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 12217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase return returnVal; 12317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 12417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 12517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 126a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * Creates a new ObjectAnimator object. This default constructor is primarily for 127d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase * use internally; the other constructors which take parameters are more generally 128d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase * useful. 129d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase */ 130a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase public ObjectAnimator() { 131d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase } 132d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase 133d51d368f2d512ab657b8ae45780c82c0dbea94c3Chet Haase /** 134d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * A constructor that takes a single property name and set of values. This constructor is 135d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * used in the simple case of animating a single property. 136fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase * 13751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @param target The object whose property is to be animated. This object should 13851ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * have a public method on it called <code>setName()</code>, where <code>name</code> is 13951ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * the value of the <code>propertyName</code> parameter. 140d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * @param propertyName The name of the property being animated. 141fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase */ 1422794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase private ObjectAnimator(Object target, String propertyName) { 14351ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mTarget = target; 144d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase setPropertyName(propertyName); 145fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase } 146fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase 147fe591563f8529305bd52e1f0640e83b9a93d562fChet Haase /** 1482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between int values. A single 1492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 1502794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 1512794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 1522794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 1532794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 1542794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 15551ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @param target The object whose property is to be animated. This object should 15651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * have a public method on it called <code>setName()</code>, where <code>name</code> is 15751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * the value of the <code>propertyName</code> parameter. 1582794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 1592794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 1602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 1612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 1622794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { 1632794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 1642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setIntValues(values); 1652794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 1662794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 1672794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 1682794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 1692794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between float values. A single 1702794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value implies that that value is the one being animated to. However, this is not typically 1712794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * useful in a ValueAnimator object because there is no way for the object to determine the 1722794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * starting value for the animation (unlike ObjectAnimator, which can derive that value 1732794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * from the target object and property being animated). Therefore, there should typically 1742794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be two or more values. 1752794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 17651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @param target The object whose property is to be animated. This object should 17751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * have a public method on it called <code>setName()</code>, where <code>name</code> is 17851ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * the value of the <code>propertyName</code> parameter. 1792794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 1802794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of values that the animation will animate between over time. 1812794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 1822794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 1832794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { 1842794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 1852794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setFloatValues(values); 1862794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 1872794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 1882794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 1892794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 190d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * A constructor that takes <code>PropertyValueHolder</code> values. This constructor should 191a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase * be used when animating several properties at once with the same ObjectAnimator, since 192d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * PropertyValuesHolder allows you to associate a set of animation values with a property 193d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * name. 19417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 19551ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @param target The object whose property is to be animated. This object should 19651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * have public methods on it called <code>setName()</code>, where <code>name</code> is 19751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * the name of the property passed in as the <code>propertyName</code> parameter for 19851ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * each of the PropertyValuesHolder objects. 1992794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param propertyName The name of the property being animated. 2002794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param evaluator A TypeEvaluator that will be called on each animation frame to 2012794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * provide the ncessry interpolation between the Object values to derive the animated 2022794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value. 203d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * @param values The PropertyValuesHolder objects which hold each the property name and values 204d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase * to animate that property between. 205d953d08e9299072130d9f4411cbcf6678bbce822Chet Haase */ 2062794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofObject(Object target, String propertyName, 2072794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase TypeEvaluator evaluator, Object... values) { 2082794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(target, propertyName); 2092794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setObjectValues(values); 2102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setEvaluator(evaluator); 2112794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 2122794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 2152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Constructs and returns an ObjectAnimator that animates between the sets of values 2162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * specifed in <code>PropertyValueHolder</code> objects. This variant should 2172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * be used when animating several properties at once with the same ObjectAnimator, since 2182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * PropertyValuesHolder allows you to associate a set of animation values with a property 2192794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * name. 2202794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 22151ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @param target The object whose property is to be animated. This object should 22251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * have public methods on it called <code>setName()</code>, where <code>name</code> is 22351ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * the name of the property passed in as the <code>propertyName</code> parameter for 22451ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * each of the PropertyValuesHolder objects. 2252794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param values A set of PropertyValuesHolder objects whose values will be animated 2262794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * between over time. 2272794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return A ValueAnimator object that is set up to animate between the given values. 2282794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 2292794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public static ObjectAnimator ofPropertyValuesHolder(Object target, 2302794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase PropertyValuesHolder... values) { 2312794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase ObjectAnimator anim = new ObjectAnimator(); 23251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy anim.mTarget = target; 2332794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase anim.setValues(values); 2342794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return anim; 2353dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase } 2363dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase 23783d6e8213230fb0805aa019d266842253baeb114Romain Guy @Override 2382794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setIntValues(int... values) { 23983d6e8213230fb0805aa019d266842253baeb114Romain Guy if (mValues == null || mValues.length == 0) { 24083d6e8213230fb0805aa019d266842253baeb114Romain Guy // No values yet - this animator is being constructed piecemeal. Init the values with 24183d6e8213230fb0805aa019d266842253baeb114Romain Guy // whatever the current propertyName is 2422794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); 24383d6e8213230fb0805aa019d266842253baeb114Romain Guy } else { 2442794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setIntValues(values); 2452794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2462794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2472794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2482794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 2492794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setFloatValues(float... values) { 2502794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 2512794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 2522794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 2532794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); 2542794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 2552794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setFloatValues(values); 2562794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2572794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 2582794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 2592794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 2602794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public void setObjectValues(Object... values) { 2612794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase if (mValues == null || mValues.length == 0) { 2622794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // No values yet - this animator is being constructed piecemeal. Init the values with 2632794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase // whatever the current propertyName is 2642794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); 2652794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } else { 2662794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setObjectValues(values); 26783d6e8213230fb0805aa019d266842253baeb114Romain Guy } 2680e0590bf3cb32e73f423c0fe39a180d4b3c4343dChet Haase } 26983d6e8213230fb0805aa019d266842253baeb114Romain Guy 270e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase @Override 271e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase public void start() { 272e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase if (DBG) { 27351ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy Log.d("ObjectAnimator", "Anim target, duration" + mTarget + ", " + getDuration()); 274e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase for (int i = 0; i < mValues.length; ++i) { 275e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase PropertyValuesHolder pvh = mValues[i]; 276e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes; 277e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase Log.d("ObjectAnimator", " Values[" + i + "]: " + 278e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " + 279e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue()); 280e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase } 281e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase } 282e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase super.start(); 283e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase } 284e2ab7ccd385cdb6517955c719e1d2b49771bedb6Chet Haase 2853dd207a6dbd5d9244dc7fe213d5caa3cddaff0dbChet Haase /** 28617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * This function is called immediately before processing the first animation 28717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * frame of an animation. If there is a nonzero <code>startDelay</code>, the 28817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function is called after that delay ends. 28917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * It takes care of the final initialization steps for the 29017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation. This includes setting mEvaluator, if the user has not yet 29117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * set it up, and the setter/getter methods, if the user did not supply 29217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * them. 29317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 29417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Overriders of this method should call the superclass method to cause 29517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * internal mechanisms to be set up correctly.</p> 29617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 29717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase @Override 29817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase void initAnimation() { 29921cd1389d2ef218b20994b617c57af120841a57fChet Haase if (!mInitialized) { 30021cd1389d2ef218b20994b617c57af120841a57fChet Haase // mValueType may change due to setter/getter setup; do this before calling super.init(), 30121cd1389d2ef218b20994b617c57af120841a57fChet Haase // which uses mValueType to set up the default type evaluator. 30221cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 30321cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 30451ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mValues[i].setupSetterAndGetter(mTarget); 30521cd1389d2ef218b20994b617c57af120841a57fChet Haase } 30621cd1389d2ef218b20994b617c57af120841a57fChet Haase super.initAnimation(); 30717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 30817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 30917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 3102794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase /** 3112794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * Sets the length of the animation. The default duration is 300 milliseconds. 3122794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * 3132794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @param duration The length of the animation, in milliseconds. 3142794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * @return ObjectAnimator The object called with setDuration(). This return 3152794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * value makes it easier to compose statements together that construct and then set the 3162794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * duration, as in 3172794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>. 3182794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase */ 3192794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase @Override 3202794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase public ObjectAnimator setDuration(long duration) { 3212794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase super.setDuration(duration); 3222794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase return this; 3232794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase } 3242794eb3b02e2404d453d3ad22a8a85a138130a07Chet Haase 32517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 32617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 32717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * The target object whose property will be animated by this animation 32817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 32951ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * @return The object being animated 33017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 33117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase public Object getTarget() { 33251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy return mTarget; 33317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 33417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase 33517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase /** 33651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy * Sets the target object whose property will be animated by this animation 337f54a8d7c479485174941c38f151ea7083c658da3Chet Haase * 338f54a8d7c479485174941c38f151ea7083c658da3Chet Haase * @param target The object being animated 339f54a8d7c479485174941c38f151ea7083c658da3Chet Haase */ 34021cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 341f54a8d7c479485174941c38f151ea7083c658da3Chet Haase public void setTarget(Object target) { 34251ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy if (mTarget != target) { 34351ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mTarget = target; 34451ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy if (mTarget != null && target != null && mTarget.getClass() == target.getClass()) { 34570d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase return; 34670d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase } 34770d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase // New target type should cause re-initialization prior to starting 34870d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase mInitialized = false; 34970d4ba15b1f0c1133c5aabc86de828b41e482fffChet Haase } 350f54a8d7c479485174941c38f151ea7083c658da3Chet Haase } 351f54a8d7c479485174941c38f151ea7083c658da3Chet Haase 35221cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 35321cd1389d2ef218b20994b617c57af120841a57fChet Haase public void setupStartValues() { 35421cd1389d2ef218b20994b617c57af120841a57fChet Haase initAnimation(); 35521cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 35621cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 35751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mValues[i].setupStartValue(mTarget); 35821cd1389d2ef218b20994b617c57af120841a57fChet Haase } 35921cd1389d2ef218b20994b617c57af120841a57fChet Haase } 36021cd1389d2ef218b20994b617c57af120841a57fChet Haase 36121cd1389d2ef218b20994b617c57af120841a57fChet Haase @Override 36221cd1389d2ef218b20994b617c57af120841a57fChet Haase public void setupEndValues() { 36321cd1389d2ef218b20994b617c57af120841a57fChet Haase initAnimation(); 36421cd1389d2ef218b20994b617c57af120841a57fChet Haase int numValues = mValues.length; 36521cd1389d2ef218b20994b617c57af120841a57fChet Haase for (int i = 0; i < numValues; ++i) { 36651ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mValues[i].setupEndValue(mTarget); 36721cd1389d2ef218b20994b617c57af120841a57fChet Haase } 36821cd1389d2ef218b20994b617c57af120841a57fChet Haase } 36921cd1389d2ef218b20994b617c57af120841a57fChet Haase 370f54a8d7c479485174941c38f151ea7083c658da3Chet Haase /** 37117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * This method is called with the elapsed fraction of the animation during every 37217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation frame. This function turns the elapsed fraction into an interpolated fraction 37317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * and then into an animated value (from the evaluator. The function is called mostly during 37417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * animation updates, but it is also called when the <code>end()</code> 37517fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * function is called, to set the final value on the property. 37617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 37717fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * <p>Overrides of this method must call the superclass to perform the calculation 37817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * of the animated value.</p> 37917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * 38017fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase * @param fraction The elapsed fraction of the animation. 38117fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase */ 38217fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase @Override 38317fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase void animateValue(float fraction) { 38417fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase super.animateValue(fraction); 385602e4d3824bf8b9cb9f817375d195b969712176aChet Haase int numValues = mValues.length; 386602e4d3824bf8b9cb9f817375d195b969712176aChet Haase for (int i = 0; i < numValues; ++i) { 38751ae5fc2d22a7bb616f432d7bac66bbbf8a1927fPatrick Dubroy mValues[i].setAnimatedValue(mTarget); 38817fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 38917fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase } 39049afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase 39149afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase @Override 392a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase public ObjectAnimator clone() { 393a18a86b43e40e3c15dcca0ae0148d641be9b25feChet Haase final ObjectAnimator anim = (ObjectAnimator) super.clone(); 39449afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase return anim; 39549afa5bc100e5d4c069fea980dd6b09501f56397Chet Haase } 39617fb4b0d1cfbad1f026fec704c86640f070b4c2fChet Haase} 397