Merge "Adding animation facilities to simplify layout transitions"

This commit is contained in:
Chet Haase
2010-08-23 13:54:07 -07:00
committed by Android (Google) Code Review
4 changed files with 100 additions and 61 deletions

View File

@@ -20080,6 +20080,17 @@
visibility="public"
>
</method>
<method name="getDuration"
return="long"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getFrameDelay"
return="long"
abstract="false"
@@ -20091,6 +20102,17 @@
visibility="public"
>
</method>
<method name="getInterpolator"
return="android.view.animation.Interpolator"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getRepeatCount"
return="int"
abstract="false"

View File

@@ -19,6 +19,7 @@ package android.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
@@ -197,15 +198,13 @@ public class Animator<T> extends Animatable {
/**
* The property/value sets being animated.
*/
HashMap<String, PropertyValuesHolder> mValues;
PropertyValuesHolder[] mValues;
/**
* This value is used in the simple/common case of animating just one value; the user
* may call getAnimatedValue(), which should return the value of the first (and only)
* ProeprtyValuesHolder animated value, which is looked up using this string.
* A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
* by property name during calls to getAnimatedValue(String).
*/
String mFirstPropertyName;
HashMap<String, PropertyValuesHolder> mValuesMap;
/**
* The type of the values, as determined by the valueFrom/valueTo properties.
@@ -290,11 +289,11 @@ public class Animator<T> extends Animatable {
break;
}
mValues = new HashMap<String, PropertyValuesHolder>(1);
mFirstPropertyName = "";
PropertyValuesHolder valuesHolder = new PropertyValuesHolder(mFirstPropertyName,
valueFrom, valueTo);
mValues.put(mFirstPropertyName, valuesHolder);
PropertyValuesHolder valuesHolder = new PropertyValuesHolder("", valueFrom, valueTo);
mValues = new PropertyValuesHolder[1];
mValues[0] = valuesHolder;
mValuesMap = new HashMap<String, PropertyValuesHolder>(1);
mValuesMap.put("", valuesHolder);
mRepeatCount = a.getInt(com.android.internal.R.styleable.Animator_repeatCount, mRepeatCount);
mRepeatMode = a.getInt(com.android.internal.R.styleable.Animator_repeatMode, RESTART);
@@ -323,15 +322,11 @@ public class Animator<T> extends Animatable {
public void setValues(PropertyValuesHolder... values) {
int numValues = values.length;
mValues = new HashMap<String, PropertyValuesHolder>(numValues);
mValues = values;
mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
mValues.put(valuesHolder.getPropertyName(), valuesHolder);
}
if (numValues > 0 && values[0] != null) {
mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
} else {
mFirstPropertyName = "";
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
}
@@ -348,26 +343,12 @@ public class Animator<T> extends Animatable {
* @param values The set of values to animate between.
*/
public void setValues(T... values) {
if (values[0] instanceof PropertyValuesHolder) {
int numValues = values.length;
mValues = new HashMap<String, PropertyValuesHolder>(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
mValues.put(valuesHolder.getPropertyName(), valuesHolder);
}
if (numValues > 0 && values[0] != null) {
mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
} else {
mFirstPropertyName = "";
}
if (mValues == null || mValues.length == 0) {
setValues(new PropertyValuesHolder[]{
new PropertyValuesHolder("", (Object[])values)});
} else {
if (mValues == null) {
setValues(new PropertyValuesHolder[]{
new PropertyValuesHolder("", (Object[])values)});
} else {
PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
valuesHolder.setValues(values);
}
PropertyValuesHolder valuesHolder = mValues[0];
valuesHolder.setValues(values);
}
}
@@ -382,8 +363,9 @@ public class Animator<T> extends Animatable {
* that internal mechanisms for the animation are set up correctly.</p>
*/
void initAnimation() {
for (PropertyValuesHolder pvHolder: mValues.values()) {
pvHolder.init();
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].init();
}
mCurrentIteration = 0;
mInitialized = true;
@@ -394,8 +376,8 @@ public class Animator<T> extends Animatable {
* be between 0 and the total duration of the animation, including any repetition. If
* the animation has not yet been started, then it will not advance forward after it is
* set to this time; it will simply set the time to this value and perform any appropriate
* actions based on that time. If the animation is already running, then seek() will
* set the current playing time to this value and continue playing from that point.
* actions based on that time. If the animation is already running, then setCurrentPlayTime()
* will set the current playing time to this value and continue playing from that point.
*
* @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
*/
@@ -587,7 +569,11 @@ public class Animator<T> extends Animatable {
* returns the animated value for the first of those objects.
*/
public Object getAnimatedValue() {
return getAnimatedValue(mFirstPropertyName);
if (mValues != null && mValues.length > 0) {
return mValues[0].getAnimatedValue();
}
// Shouldn't get here; should always have values unless Animator was set up wrong
return null;
}
/**
@@ -601,7 +587,13 @@ public class Animator<T> extends Animatable {
* by this <code>Animator</code>.
*/
public Object getAnimatedValue(String propertyName) {
return mValues.get(mFirstPropertyName).getAnimatedValue();
PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
if (valuesHolder != null) {
return valuesHolder.getAnimatedValue();
} else {
// At least avoid crashing if called with bogus propertyName
return null;
}
}
/**
@@ -690,6 +682,15 @@ public class Animator<T> extends Animatable {
}
}
/**
* Returns the timing interpolator that this Animator uses.
*
* @return The timing interpolator for this Animator.
*/
public Interpolator getInterpolator() {
return mInterpolator;
}
/**
* The type evaluator to be used when calculating the animated values of this animation.
* The system will automatically assign a float, int, or double evaluator based on the type
@@ -707,8 +708,8 @@ public class Animator<T> extends Animatable {
* @param value the evaluator to be used this animation
*/
public void setEvaluator(TypeEvaluator value) {
if (value != null && mValues != null) {
mValues.get(mFirstPropertyName).setEvaluator(value);
if (value != null && mValues != null && mValues.length > 0) {
mValues[0].setEvaluator(value);
}
}
@@ -720,6 +721,10 @@ public class Animator<T> extends Animatable {
* @param playBackwards Whether the Animator should start playing in reverse.
*/
private void start(boolean playBackwards) {
if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
// This sets the initial value of the animation, prior to actually starting it running
setCurrentPlayTime(getCurrentPlayTime());
}
mPlayingBackwards = playBackwards;
mPlayingState = STOPPED;
sPendingAnimations.add(this);
@@ -731,6 +736,15 @@ public class Animator<T> extends Animatable {
sAnimationHandler.sendEmptyMessage(ANIMATION_START);
}
/**
* Returns the duration that this animation will run for.
*
* @return The length in time of the animation, in milliseconds.
*/
public long getDuration() {
return mDuration;
}
@Override
public void start() {
start(false);
@@ -928,8 +942,9 @@ public class Animator<T> extends Animatable {
*/
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
for (PropertyValuesHolder valuesHolder : mValues.values()) {
valuesHolder.calculateValue(fraction);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();

View File

@@ -21,10 +21,7 @@ import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* This subclass of {@link Animator} provides support for animating properties on target objects.
@@ -61,10 +58,12 @@ public final class PropertyAnimator<T> extends Animator<T> {
*/
public void setPropertyName(String propertyName) {
if (mValues != null) {
// should always be the case
PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
// mValues should always be non-null
PropertyValuesHolder valuesHolder = mValues[0];
String oldName = valuesHolder.getPropertyName();
valuesHolder.setPropertyName(propertyName);
mFirstPropertyName = propertyName;
mValuesMap.remove(oldName);
mValuesMap.put(propertyName, valuesHolder);
}
mPropertyName = propertyName;
}
@@ -184,8 +183,9 @@ public final class PropertyAnimator<T> extends Animator<T> {
@Override
void initAnimation() {
super.initAnimation();
for (PropertyValuesHolder valuesHolder : mValues.values()) {
valuesHolder.setupSetterAndGetter(mTarget);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].setupSetterAndGetter(mTarget);
}
}
@@ -223,8 +223,9 @@ public final class PropertyAnimator<T> extends Animator<T> {
@Override
void animateValue(float fraction) {
super.animateValue(fraction);
for (PropertyValuesHolder valuesHolder : mValues.values()) {
valuesHolder.setAnimatedValue(mTarget);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].setAnimatedValue(mTarget);
}
}
}

View File

@@ -261,11 +261,12 @@ public class PropertyValuesHolder<T> {
// Swallow the error and keep trying other variants
}
}
// If we got here, then no appropriate function was found
Log.e("PropertyValuesHolder",
"Couldn't find setter/getter for property " + mPropertyName +
"with value type "+ mValueType);
}
// If we got here, then no appropriate function was found
Log.e("PropertyValuesHolder",
"Couldn't find setter/getter for property " + mPropertyName +
"with value type "+ mValueType);
return returnVal;
}