Merge "Rename several animation classes"
This commit is contained in:
950
api/current.xml
950
api/current.xml
File diff suppressed because it is too large
Load Diff
@@ -1,248 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.animation;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* This is the superclass for classes which provide basic support for animations which can be
|
||||
* started, ended, and have <code>AnimatableListeners</code> added to them.
|
||||
*/
|
||||
public abstract class Animatable implements Cloneable {
|
||||
|
||||
|
||||
/**
|
||||
* The set of listeners to be sent events through the life of an animation.
|
||||
*/
|
||||
ArrayList<AnimatableListener> mListeners = null;
|
||||
|
||||
/**
|
||||
* Starts this animation. If the animation has a nonzero startDelay, the animation will start
|
||||
* running after that delay elapses. Note that the animation does not start synchronously with
|
||||
* this call, because all animation events are posted to a central timing loop so that animation
|
||||
* times are all synchronized on a single timing pulse on the UI thread. So the animation will
|
||||
* start the next time that event handler processes events.
|
||||
*/
|
||||
public void start() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the animation. Unlike {@link #end()}, <code>cancel()</code> causes the animation to
|
||||
* stop in its tracks, sending an {@link AnimatableListener#onAnimationCancel(Animatable)} to
|
||||
* its listeners, followed by an {@link AnimatableListener#onAnimationEnd(Animatable)} message.
|
||||
*/
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the animation. This causes the animation to assign the end value of the property being
|
||||
* animated, then calling the {@link AnimatableListener#onAnimationEnd(Animatable)} method on
|
||||
* its listeners.
|
||||
*/
|
||||
public void end() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, to delay starting the animation after
|
||||
* {@link #start()} is called.
|
||||
*
|
||||
* @return the number of milliseconds to delay running the animation
|
||||
*/
|
||||
public abstract long getStartDelay();
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, to delay starting the animation after
|
||||
* {@link #start()} is called.
|
||||
|
||||
* @param startDelay The amount of the delay, in milliseconds
|
||||
*/
|
||||
public abstract void setStartDelay(long startDelay);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the length of the animation.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
*/
|
||||
public abstract void setDuration(long duration);
|
||||
|
||||
/**
|
||||
* Gets the length of the animation.
|
||||
*
|
||||
* @return The length of the animation, in milliseconds.
|
||||
*/
|
||||
public abstract long getDuration();
|
||||
|
||||
/**
|
||||
* The time interpolator used in calculating the elapsed fraction of this animation. The
|
||||
* interpolator determines whether the animation runs with linear or non-linear motion,
|
||||
* such as acceleration and deceleration. The default value is
|
||||
* {@link android.view.animation.AccelerateDecelerateInterpolator}
|
||||
*
|
||||
* @param value the interpolator to be used by this animation
|
||||
*/
|
||||
public abstract void setInterpolator(Interpolator value);
|
||||
|
||||
/**
|
||||
* Returns whether this Animatable is currently running (having been started and not yet ended).
|
||||
* @return Whether the Animatable is running.
|
||||
*/
|
||||
public abstract boolean isRunning();
|
||||
|
||||
/**
|
||||
* Adds a listener to the set of listeners that are sent events through the life of an
|
||||
* animation, such as start, repeat, and end.
|
||||
*
|
||||
* @param listener the listener to be added to the current set of listeners for this animation.
|
||||
*/
|
||||
public void addListener(AnimatableListener listener) {
|
||||
if (mListeners == null) {
|
||||
mListeners = new ArrayList<AnimatableListener>();
|
||||
}
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from the set listening to this animation.
|
||||
*
|
||||
* @param listener the listener to be removed from the current set of listeners for this
|
||||
* animation.
|
||||
*/
|
||||
public void removeListener(AnimatableListener listener) {
|
||||
if (mListeners == null) {
|
||||
return;
|
||||
}
|
||||
mListeners.remove(listener);
|
||||
if (mListeners.size() == 0) {
|
||||
mListeners = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of {@link AnimatableListener} objects that are currently
|
||||
* listening for events on this <code>Animatable</code> object.
|
||||
*
|
||||
* @return ArrayList<AnimatableListener> The set of listeners.
|
||||
*/
|
||||
public ArrayList<AnimatableListener> getListeners() {
|
||||
return mListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all listeners from this object. This is equivalent to calling
|
||||
* <code>getListeners()</code> followed by calling <code>clear()</code> on the
|
||||
* returned list of listeners.
|
||||
*/
|
||||
public void removeAllListeners() {
|
||||
if (mListeners != null) {
|
||||
mListeners.clear();
|
||||
mListeners = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animatable clone() {
|
||||
try {
|
||||
final Animatable anim = (Animatable) super.clone();
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatableListener> oldListeners = mListeners;
|
||||
anim.mListeners = new ArrayList<AnimatableListener>();
|
||||
int numListeners = oldListeners.size();
|
||||
for (int i = 0; i < numListeners; ++i) {
|
||||
anim.mListeners.add(oldListeners.get(i));
|
||||
}
|
||||
}
|
||||
return anim;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tells the object to use appropriate information to extract
|
||||
* starting values for the animation. For example, a Sequencer object will pass
|
||||
* this call to its child objects to tell them to set up the values. A
|
||||
* PropertyAnimator object will use the information it has about its target object
|
||||
* and PropertyValuesHolder objects to get the start values for its properties.
|
||||
* An Animator object will ignore the request since it does not have enough
|
||||
* information (such as a target object) to gather these values.
|
||||
*/
|
||||
public void setupStartValues() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tells the object to use appropriate information to extract
|
||||
* ending values for the animation. For example, a Sequencer object will pass
|
||||
* this call to its child objects to tell them to set up the values. A
|
||||
* PropertyAnimator object will use the information it has about its target object
|
||||
* and PropertyValuesHolder objects to get the start values for its properties.
|
||||
* An Animator object will ignore the request since it does not have enough
|
||||
* information (such as a target object) to gather these values.
|
||||
*/
|
||||
public void setupEndValues() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target object whose property will be animated by this animation. Not all subclasses
|
||||
* operate on target objects (for example, {@link android.animation.Animator}, but this method
|
||||
* is on the superclass for the convenience of dealing generically with those subclasses
|
||||
* that do handle targets.
|
||||
*
|
||||
* @param target The object being animated
|
||||
*/
|
||||
public void setTarget(Object target) {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>An animation listener receives notifications from an animation.
|
||||
* Notifications indicate animation related events, such as the end or the
|
||||
* repetition of the animation.</p>
|
||||
*/
|
||||
public static interface AnimatableListener {
|
||||
/**
|
||||
* <p>Notifies the start of the animation.</p>
|
||||
*
|
||||
* @param animation The started animation.
|
||||
*/
|
||||
void onAnimationStart(Animatable animation);
|
||||
|
||||
/**
|
||||
* <p>Notifies the end of the animation. This callback is not invoked
|
||||
* for animations with repeat count set to INFINITE.</p>
|
||||
*
|
||||
* @param animation The animation which reached its end.
|
||||
*/
|
||||
void onAnimationEnd(Animatable animation);
|
||||
|
||||
/**
|
||||
* <p>Notifies the cancellation of the animation. This callback is not invoked
|
||||
* for animations with repeat count set to INFINITE.</p>
|
||||
*
|
||||
* @param animation The animation which was canceled.
|
||||
*/
|
||||
void onAnimationCancel(Animatable animation);
|
||||
|
||||
/**
|
||||
* <p>Notifies the repetition of the animation.</p>
|
||||
*
|
||||
* @param animation The animation which was repeated.
|
||||
*/
|
||||
void onAnimationRepeat(Animatable animation);
|
||||
}
|
||||
}
|
||||
1023
core/java/android/animation/Animator.java
Executable file → Normal file
1023
core/java/android/animation/Animator.java
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* This class is used to instantiate menu XML files into Animatable objects.
|
||||
* This class is used to instantiate menu XML files into Animator objects.
|
||||
* <p>
|
||||
* For performance reasons, menu inflation relies heavily on pre-processing of
|
||||
* XML files that is done at build time. Therefore, it is not currently possible
|
||||
@@ -38,10 +38,10 @@ import java.util.ArrayList;
|
||||
* it only works with an XmlPullParser returned from a compiled resource (R.
|
||||
* <em>something</em> file.)
|
||||
*/
|
||||
public class AnimatableInflater {
|
||||
public class AnimatorInflater {
|
||||
|
||||
/**
|
||||
* These flags are used when parsing Sequencer objects
|
||||
* These flags are used when parsing AnimatorSet objects
|
||||
*/
|
||||
private static final int TOGETHER = 0;
|
||||
private static final int SEQUENTIALLY = 1;
|
||||
@@ -56,20 +56,20 @@ public class AnimatableInflater {
|
||||
private static final int VALUE_TYPE_CUSTOM = 4;
|
||||
|
||||
/**
|
||||
* Loads an {@link Animatable} object from a resource
|
||||
* Loads an {@link Animator} object from a resource
|
||||
*
|
||||
* @param context Application context used to access resources
|
||||
* @param id The resource id of the animation to load
|
||||
* @return The animatable object reference by the specified id
|
||||
* @return The animator object reference by the specified id
|
||||
* @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded
|
||||
*/
|
||||
public static Animatable loadAnimatable(Context context, int id)
|
||||
public static Animator loadAnimator(Context context, int id)
|
||||
throws NotFoundException {
|
||||
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = context.getResources().getAnimation(id);
|
||||
return createAnimatableFromXml(context, parser);
|
||||
return createAnimatorFromXml(context, parser);
|
||||
} catch (XmlPullParserException ex) {
|
||||
Resources.NotFoundException rnf =
|
||||
new Resources.NotFoundException("Can't load animation resource ID #0x" +
|
||||
@@ -87,18 +87,18 @@ public class AnimatableInflater {
|
||||
}
|
||||
}
|
||||
|
||||
private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser)
|
||||
private static Animator createAnimatorFromXml(Context c, XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
return createAnimatableFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
|
||||
return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0);
|
||||
}
|
||||
|
||||
private static Animatable createAnimatableFromXml(Context c, XmlPullParser parser,
|
||||
AttributeSet attrs, Sequencer parent, int sequenceOrdering)
|
||||
private static Animator createAnimatorFromXml(Context c, XmlPullParser parser,
|
||||
AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
|
||||
throws XmlPullParserException, IOException {
|
||||
|
||||
Animatable anim = null;
|
||||
ArrayList<Animatable> childAnims = null;
|
||||
Animator anim = null;
|
||||
ArrayList<Animator> childAnims = null;
|
||||
|
||||
// Make sure we are on a start tag.
|
||||
int type;
|
||||
@@ -113,17 +113,17 @@ public class AnimatableInflater {
|
||||
|
||||
String name = parser.getName();
|
||||
|
||||
if (name.equals("property")) {
|
||||
anim = loadPropertyAnimator(c, attrs);
|
||||
if (name.equals("objectAnimator")) {
|
||||
anim = loadObjectAnimator(c, attrs);
|
||||
} else if (name.equals("animator")) {
|
||||
anim = loadAnimator(c, attrs, null);
|
||||
} else if (name.equals("sequencer")) {
|
||||
anim = new Sequencer();
|
||||
} else if (name.equals("set")) {
|
||||
anim = new AnimatorSet();
|
||||
TypedArray a = c.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.Sequencer);
|
||||
int ordering = a.getInt(com.android.internal.R.styleable.Sequencer_ordering,
|
||||
com.android.internal.R.styleable.AnimatorSet);
|
||||
int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering,
|
||||
TOGETHER);
|
||||
createAnimatableFromXml(c, parser, attrs, (Sequencer) anim, ordering);
|
||||
createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim, ordering);
|
||||
a.recycle();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown animator name: " + parser.getName());
|
||||
@@ -131,15 +131,15 @@ public class AnimatableInflater {
|
||||
|
||||
if (parent != null) {
|
||||
if (childAnims == null) {
|
||||
childAnims = new ArrayList<Animatable>();
|
||||
childAnims = new ArrayList<Animator>();
|
||||
}
|
||||
childAnims.add(anim);
|
||||
}
|
||||
}
|
||||
if (parent != null && childAnims != null) {
|
||||
Animatable[] animsArray = new Animatable[childAnims.size()];
|
||||
Animator[] animsArray = new Animator[childAnims.size()];
|
||||
int index = 0;
|
||||
for (Animatable a : childAnims) {
|
||||
for (Animator a : childAnims) {
|
||||
animsArray[index++] = a;
|
||||
}
|
||||
if (sequenceOrdering == TOGETHER) {
|
||||
@@ -153,10 +153,10 @@ public class AnimatableInflater {
|
||||
|
||||
}
|
||||
|
||||
private static PropertyAnimator loadPropertyAnimator(Context context, AttributeSet attrs)
|
||||
private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs)
|
||||
throws NotFoundException {
|
||||
|
||||
PropertyAnimator anim = new PropertyAnimator();
|
||||
ObjectAnimator anim = new ObjectAnimator();
|
||||
|
||||
loadAnimator(context, attrs, anim);
|
||||
|
||||
@@ -179,7 +179,7 @@ public class AnimatableInflater {
|
||||
* @param context the application environment
|
||||
* @param attrs the set of attributes holding the animation parameters
|
||||
*/
|
||||
private static Animator loadAnimator(Context context, AttributeSet attrs, Animator anim)
|
||||
private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim)
|
||||
throws NotFoundException {
|
||||
|
||||
TypedArray a =
|
||||
@@ -236,7 +236,7 @@ public class AnimatableInflater {
|
||||
}
|
||||
|
||||
if (anim == null) {
|
||||
anim = new Animator(duration, valueFrom, valueTo);
|
||||
anim = new ValueAnimator(duration, valueFrom, valueTo);
|
||||
} else {
|
||||
anim.setDuration(duration);
|
||||
anim.setValues(valueFrom, valueTo);
|
||||
@@ -251,7 +251,7 @@ public class AnimatableInflater {
|
||||
if (a.hasValue(com.android.internal.R.styleable.Animator_repeatMode)) {
|
||||
anim.setRepeatMode(
|
||||
a.getInt(com.android.internal.R.styleable.Animator_repeatMode,
|
||||
Animator.RESTART));
|
||||
ValueAnimator.RESTART));
|
||||
}
|
||||
if (evaluator != null) {
|
||||
anim.setEvaluator(evaluator);
|
||||
@@ -16,41 +16,39 @@
|
||||
|
||||
package android.animation;
|
||||
|
||||
import android.animation.Animatable.AnimatableListener;
|
||||
|
||||
/**
|
||||
* This adapter class provides empty implementations of the methods from {@link AnimatableListener}.
|
||||
* This adapter class provides empty implementations of the methods from {@link android.animation.Animator.AnimatorListener}.
|
||||
* Any custom listener that cares only about a subset of the methods of this listener can
|
||||
* simply subclass this adapter class instead of implementing the interface directly.
|
||||
*/
|
||||
public abstract class AnimatableListenerAdapter implements AnimatableListener {
|
||||
public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@Override
|
||||
public void onAnimationCancel(Animatable animation) {
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@Override
|
||||
public void onAnimationEnd(Animatable animation) {
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@Override
|
||||
public void onAnimationRepeat(Animatable animation) {
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@Override
|
||||
public void onAnimationStart(Animatable animation) {
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,35 +16,31 @@
|
||||
|
||||
package android.animation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class plays a set of {@link Animatable} objects in the specified order. Animations
|
||||
* This class plays a set of {@link Animator} objects in the specified order. Animations
|
||||
* can be set up to play together, in sequence, or after a specified delay.
|
||||
*
|
||||
* <p>There are two different approaches to adding animations to a <code>Sequencer</code>:
|
||||
* either the {@link Sequencer#playTogether(Animatable[]) playTogether()} or
|
||||
* {@link Sequencer#playSequentially(Animatable[]) playSequentially()} methods can be called to add
|
||||
* a set of animations all at once, or the {@link Sequencer#play(Animatable)} can be
|
||||
* used in conjunction with methods in the {@link android.animation.Sequencer.Builder Builder}
|
||||
* <p>There are two different approaches to adding animations to a <code>AnimatorSet</code>:
|
||||
* either the {@link AnimatorSet#playTogether(Animator[]) playTogether()} or
|
||||
* {@link AnimatorSet#playSequentially(Animator[]) playSequentially()} methods can be called to add
|
||||
* a set of animations all at once, or the {@link AnimatorSet#play(Animator)} can be
|
||||
* used in conjunction with methods in the {@link AnimatorSet.Builder Builder}
|
||||
* class to add animations
|
||||
* one by one.</p>
|
||||
*
|
||||
* <p>It is possible to set up a <code>Sequencer</code> with circular dependencies between
|
||||
* <p>It is possible to set up a <code>AnimatorSet</code> with circular dependencies between
|
||||
* its animations. For example, an animation a1 could be set up to start before animation a2, a2
|
||||
* before a3, and a3 before a1. The results of this configuration are undefined, but will typically
|
||||
* result in none of the affected animations being played. Because of this (and because
|
||||
* circular dependencies do not make logical sense anyway), circular dependencies
|
||||
* should be avoided, and the dependency flow of animations should only be in one direction.
|
||||
*/
|
||||
public final class Sequencer extends Animatable {
|
||||
public final class AnimatorSet extends Animator {
|
||||
|
||||
/**
|
||||
* Internal variables
|
||||
@@ -55,21 +51,21 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Tracks animations currently being played, so that we know what to
|
||||
* cancel or end when cancel() or end() is called on this Sequencer
|
||||
* cancel or end when cancel() or end() is called on this AnimatorSet
|
||||
*/
|
||||
private ArrayList<Animatable> mPlayingSet = new ArrayList<Animatable>();
|
||||
private ArrayList<Animator> mPlayingSet = new ArrayList<Animator>();
|
||||
|
||||
/**
|
||||
* Contains all nodes, mapped to their respective Animatables. When new
|
||||
* dependency information is added for an Animatable, we want to add it
|
||||
* to a single node representing that Animatable, not create a new Node
|
||||
* Contains all nodes, mapped to their respective Animators. When new
|
||||
* dependency information is added for an Animator, we want to add it
|
||||
* to a single node representing that Animator, not create a new Node
|
||||
* if one already exists.
|
||||
*/
|
||||
private HashMap<Animatable, Node> mNodeMap = new HashMap<Animatable, Node>();
|
||||
private HashMap<Animator, Node> mNodeMap = new HashMap<Animator, Node>();
|
||||
|
||||
/**
|
||||
* Set of all nodes created for this Sequencer. This list is used upon
|
||||
* starting the sequencer, and the nodes are placed in sorted order into the
|
||||
* Set of all nodes created for this AnimatorSet. This list is used upon
|
||||
* starting the set, and the nodes are placed in sorted order into the
|
||||
* sortedNodes collection.
|
||||
*/
|
||||
private ArrayList<Node> mNodes = new ArrayList<Node>();
|
||||
@@ -88,12 +84,12 @@ public final class Sequencer extends Animatable {
|
||||
*/
|
||||
private boolean mNeedsSort = true;
|
||||
|
||||
private SequencerAnimatableListener mSequenceListener = null;
|
||||
private AnimatorSetListener mSetListener = null;
|
||||
|
||||
/**
|
||||
* Flag indicating that the Sequencer has been canceled (by calling cancel() or end()).
|
||||
* Flag indicating that the AnimatorSet has been canceled (by calling cancel() or end()).
|
||||
* This flag is used to avoid starting other animations when currently-playing
|
||||
* child animations of this Sequencer end.
|
||||
* child animations of this AnimatorSet end.
|
||||
*/
|
||||
boolean mCanceled = false;
|
||||
|
||||
@@ -102,55 +98,55 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
|
||||
// How long the child animations should last in ms. The default value is negative, which
|
||||
// simply means that there is no duration set on the Sequencer. When a real duration is
|
||||
// simply means that there is no duration set on the AnimatorSet. When a real duration is
|
||||
// set, it is passed along to the child animations.
|
||||
private long mDuration = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Sets up this Sequencer to play all of the supplied animations at the same time.
|
||||
* Sets up this AnimatorSet to play all of the supplied animations at the same time.
|
||||
*
|
||||
* @param sequenceItems The animations that will be started simultaneously.
|
||||
* @param items The animations that will be started simultaneously.
|
||||
*/
|
||||
public void playTogether(Animatable... sequenceItems) {
|
||||
if (sequenceItems != null) {
|
||||
public void playTogether(Animator... items) {
|
||||
if (items != null) {
|
||||
mNeedsSort = true;
|
||||
Builder builder = play(sequenceItems[0]);
|
||||
for (int i = 1; i < sequenceItems.length; ++i) {
|
||||
builder.with(sequenceItems[i]);
|
||||
Builder builder = play(items[0]);
|
||||
for (int i = 1; i < items.length; ++i) {
|
||||
builder.with(items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up this Sequencer to play each of the supplied animations when the
|
||||
* Sets up this AnimatorSet to play each of the supplied animations when the
|
||||
* previous animation ends.
|
||||
*
|
||||
* @param sequenceItems The aniamtions that will be started one after another.
|
||||
* @param items The aniamtions that will be started one after another.
|
||||
*/
|
||||
public void playSequentially(Animatable... sequenceItems) {
|
||||
if (sequenceItems != null) {
|
||||
public void playSequentially(Animator... items) {
|
||||
if (items != null) {
|
||||
mNeedsSort = true;
|
||||
if (sequenceItems.length == 1) {
|
||||
play(sequenceItems[0]);
|
||||
if (items.length == 1) {
|
||||
play(items[0]);
|
||||
} else {
|
||||
for (int i = 0; i < sequenceItems.length - 1; ++i) {
|
||||
play(sequenceItems[i]).before(sequenceItems[i+1]);
|
||||
for (int i = 0; i < items.length - 1; ++i) {
|
||||
play(items[i]).before(items[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current list of child Animatable objects controlled by this
|
||||
* Sequencer. This is a copy of the internal list; modifications to the returned list
|
||||
* will not affect the Sequencer, although changes to the underlying Animatable objects
|
||||
* will affect those objects being managed by the Sequencer.
|
||||
* Returns the current list of child Animator objects controlled by this
|
||||
* AnimatorSet. This is a copy of the internal list; modifications to the returned list
|
||||
* will not affect the AnimatorSet, although changes to the underlying Animator objects
|
||||
* will affect those objects being managed by the AnimatorSet.
|
||||
*
|
||||
* @return ArrayList<Animatable> The list of child animations of this Sequencer.
|
||||
* @return ArrayList<Animator> The list of child animations of this AnimatorSet.
|
||||
*/
|
||||
public ArrayList<Animatable> getChildAnimations() {
|
||||
ArrayList<Animatable> childList = new ArrayList<Animatable>();
|
||||
public ArrayList<Animator> getChildAnimations() {
|
||||
ArrayList<Animator> childList = new ArrayList<Animator>();
|
||||
for (Node node : mNodes) {
|
||||
childList.add(node.animation);
|
||||
}
|
||||
@@ -159,28 +155,28 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Sets the target object for all current {@link #getChildAnimations() child animations}
|
||||
* of this Sequencer that take targets ({@link android.animation.PropertyAnimator} and
|
||||
* Sequencer).
|
||||
* of this AnimatorSet that take targets ({@link ObjectAnimator} and
|
||||
* AnimatorSet).
|
||||
*
|
||||
* @param target The object being animated
|
||||
*/
|
||||
@Override
|
||||
public void setTarget(Object target) {
|
||||
for (Node node : mNodes) {
|
||||
Animatable animation = node.animation;
|
||||
if (animation instanceof Sequencer) {
|
||||
((Sequencer)animation).setTarget(target);
|
||||
} else if (animation instanceof PropertyAnimator) {
|
||||
((PropertyAnimator)animation).setTarget(target);
|
||||
Animator animation = node.animation;
|
||||
if (animation instanceof AnimatorSet) {
|
||||
((AnimatorSet)animation).setTarget(target);
|
||||
} else if (animation instanceof ObjectAnimator) {
|
||||
((ObjectAnimator)animation).setTarget(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Interpolator for all current {@link #getChildAnimations() child animations}
|
||||
* of this Sequencer.
|
||||
* of this AnimatorSet.
|
||||
*
|
||||
* @param interpolator the interpolator to be used by each child animation of this Sequencer
|
||||
* @param interpolator the interpolator to be used by each child animation of this AnimatorSet
|
||||
*/
|
||||
@Override
|
||||
public void setInterpolator(Interpolator interpolator) {
|
||||
@@ -194,11 +190,11 @@ public final class Sequencer extends Animatable {
|
||||
* set up playing constraints. This initial <code>play()</code> method
|
||||
* tells the <code>Builder</code> the animation that is the dependency for
|
||||
* the succeeding commands to the <code>Builder</code>. For example,
|
||||
* calling <code>play(a1).with(a2)</code> sets up the Sequence to play
|
||||
* calling <code>play(a1).with(a2)</code> sets up the AnimatorSet to play
|
||||
* <code>a1</code> and <code>a2</code> at the same time,
|
||||
* <code>play(a1).before(a2)</code> sets up the Sequence to play
|
||||
* <code>play(a1).before(a2)</code> sets up the AnimatorSet to play
|
||||
* <code>a1</code> first, followed by <code>a2</code>, and
|
||||
* <code>play(a1).after(a2)</code> sets up the Sequence to play
|
||||
* <code>play(a1).after(a2)</code> sets up the AnimatorSet to play
|
||||
* <code>a2</code> first, followed by <code>a1</code>.
|
||||
*
|
||||
* <p>Note that <code>play()</code> is the only way to tell the
|
||||
@@ -213,11 +209,11 @@ public final class Sequencer extends Animatable {
|
||||
* @param anim The animation that is the dependency used in later calls to the
|
||||
* methods in the returned <code>Builder</code> object. A null parameter will result
|
||||
* in a null <code>Builder</code> return value.
|
||||
* @return Builder The object that constructs the sequence based on the dependencies
|
||||
* @return Builder The object that constructs the AnimatorSet based on the dependencies
|
||||
* outlined in the calls to <code>play</code> and the other methods in the
|
||||
* <code>Builder</code object.
|
||||
*/
|
||||
public Builder play(Animatable anim) {
|
||||
public Builder play(Animator anim) {
|
||||
if (anim != null) {
|
||||
mNeedsSort = true;
|
||||
return new Builder(anim);
|
||||
@@ -228,7 +224,7 @@ public final class Sequencer extends Animatable {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Note that canceling a <code>Sequencer</code> also cancels all of the animations that it is
|
||||
* <p>Note that canceling a <code>AnimatorSet</code> also cancels all of the animations that it is
|
||||
* responsible for.</p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -236,9 +232,9 @@ public final class Sequencer extends Animatable {
|
||||
public void cancel() {
|
||||
mCanceled = true;
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatableListener> tmpListeners =
|
||||
(ArrayList<AnimatableListener>) mListeners.clone();
|
||||
for (AnimatableListener listener : tmpListeners) {
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationCancel(this);
|
||||
}
|
||||
}
|
||||
@@ -252,7 +248,7 @@ public final class Sequencer extends Animatable {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Note that ending a <code>Sequencer</code> also ends all of the animations that it is
|
||||
* <p>Note that ending a <code>AnimatorSet</code> also ends all of the animations that it is
|
||||
* responsible for.</p>
|
||||
*/
|
||||
@Override
|
||||
@@ -262,10 +258,10 @@ public final class Sequencer extends Animatable {
|
||||
// hasn't been started yet - sort the nodes now, then end them
|
||||
sortNodes();
|
||||
for (Node node : mSortedNodes) {
|
||||
if (mSequenceListener == null) {
|
||||
mSequenceListener = new SequencerAnimatableListener(this);
|
||||
if (mSetListener == null) {
|
||||
mSetListener = new AnimatorSetListener(this);
|
||||
}
|
||||
node.animation.addListener(mSequenceListener);
|
||||
node.animation.addListener(mSetListener);
|
||||
}
|
||||
}
|
||||
if (mSortedNodes.size() > 0) {
|
||||
@@ -276,9 +272,9 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any of the child animations of this Sequencer have been started and have not
|
||||
* Returns true if any of the child animations of this AnimatorSet have been started and have not
|
||||
* yet ended.
|
||||
* @return Whether this Sequencer has been started and has not yet ended.
|
||||
* @return Whether this AnimatorSet has been started and has not yet ended.
|
||||
*/
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
@@ -313,12 +309,12 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of each of the child animations of this Sequencer. This value may
|
||||
* be less than 0, which indicates that no duration has been set on this Sequencer
|
||||
* Gets the length of each of the child animations of this AnimatorSet. This value may
|
||||
* be less than 0, which indicates that no duration has been set on this AnimatorSet
|
||||
* and each of the child animations will use their own duration.
|
||||
*
|
||||
* @return The length of the animation, in milliseconds, of each of the child
|
||||
* animations of this Sequencer.
|
||||
* animations of this AnimatorSet.
|
||||
*/
|
||||
@Override
|
||||
public long getDuration() {
|
||||
@@ -326,12 +322,12 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of each of the current child animations of this Sequencer. By default,
|
||||
* each child animation will use its own duration. If the duration is set on the Sequencer,
|
||||
* Sets the length of each of the current child animations of this AnimatorSet. By default,
|
||||
* each child animation will use its own duration. If the duration is set on the AnimatorSet,
|
||||
* then each child animation inherits this duration.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds, of each of the child
|
||||
* animations of this Sequencer.
|
||||
* animations of this AnimatorSet.
|
||||
*/
|
||||
@Override
|
||||
public void setDuration(long duration) {
|
||||
@@ -339,7 +335,7 @@ public final class Sequencer extends Animatable {
|
||||
throw new IllegalArgumentException("duration must be a value of zero or greater");
|
||||
}
|
||||
for (Node node : mNodes) {
|
||||
// TODO: don't set the duration of the timing-only nodes created by Sequencer to
|
||||
// TODO: don't set the duration of the timing-only nodes created by AnimatorSet to
|
||||
// insert "play-after" delays
|
||||
node.animation.setDuration(duration);
|
||||
}
|
||||
@@ -349,7 +345,7 @@ public final class Sequencer extends Animatable {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>Starting this <code>Sequencer</code> will, in turn, start the animations for which
|
||||
* <p>Starting this <code>AnimatorSet</code> will, in turn, start the animations for which
|
||||
* it is responsible. The details of when exactly those animations are started depends on
|
||||
* the dependency relationships that have been set up between the animations.
|
||||
*/
|
||||
@@ -368,8 +364,8 @@ public final class Sequencer extends Animatable {
|
||||
// when some other animation also wants to start when the first animation begins.
|
||||
final ArrayList<Node> nodesToStart = new ArrayList<Node>();
|
||||
for (Node node : mSortedNodes) {
|
||||
if (mSequenceListener == null) {
|
||||
mSequenceListener = new SequencerAnimatableListener(this);
|
||||
if (mSetListener == null) {
|
||||
mSetListener = new AnimatorSetListener(this);
|
||||
}
|
||||
if (node.dependencies == null || node.dependencies.size() == 0) {
|
||||
nodesToStart.add(node);
|
||||
@@ -380,7 +376,7 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
|
||||
}
|
||||
node.animation.addListener(mSequenceListener);
|
||||
node.animation.addListener(mSetListener);
|
||||
}
|
||||
// Now that all dependencies are set up, start the animations that should be started.
|
||||
if (mStartDelay <= 0) {
|
||||
@@ -390,9 +386,9 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
} else {
|
||||
// TODO: Need to cancel out of the delay appropriately
|
||||
Animator delayAnim = new Animator(mStartDelay, 0f, 1f);
|
||||
delayAnim.addListener(new AnimatableListenerAdapter() {
|
||||
public void onAnimationEnd(Animatable anim) {
|
||||
ValueAnimator delayAnim = new ValueAnimator(mStartDelay, 0f, 1f);
|
||||
delayAnim.addListener(new AnimatorListenerAdapter() {
|
||||
public void onAnimationEnd(Animator anim) {
|
||||
for (Node node : nodesToStart) {
|
||||
node.animation.start();
|
||||
mPlayingSet.add(node.animation);
|
||||
@@ -401,20 +397,20 @@ public final class Sequencer extends Animatable {
|
||||
});
|
||||
}
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatableListener> tmpListeners =
|
||||
(ArrayList<AnimatableListener>) mListeners.clone();
|
||||
for (AnimatableListener listener : tmpListeners) {
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationStart(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sequencer clone() {
|
||||
final Sequencer anim = (Sequencer) super.clone();
|
||||
public AnimatorSet clone() {
|
||||
final AnimatorSet anim = (AnimatorSet) super.clone();
|
||||
/*
|
||||
* The basic clone() operation copies all items. This doesn't work very well for
|
||||
* Sequencer, because it will copy references that need to be recreated and state
|
||||
* AnimatorSet, because it will copy references that need to be recreated and state
|
||||
* that may not apply. What we need to do now is put the clone in an uninitialized
|
||||
* state, with fresh, empty data structures. Then we will build up the nodes list
|
||||
* manually, as we clone each Node (and its animation). The clone will then be sorted,
|
||||
@@ -422,13 +418,13 @@ public final class Sequencer extends Animatable {
|
||||
*/
|
||||
anim.mNeedsSort = true;
|
||||
anim.mCanceled = false;
|
||||
anim.mPlayingSet = new ArrayList<Animatable>();
|
||||
anim.mNodeMap = new HashMap<Animatable, Node>();
|
||||
anim.mPlayingSet = new ArrayList<Animator>();
|
||||
anim.mNodeMap = new HashMap<Animator, Node>();
|
||||
anim.mNodes = new ArrayList<Node>();
|
||||
anim.mSortedNodes = new ArrayList<Node>();
|
||||
|
||||
// Walk through the old nodes list, cloning each node and adding it to the new nodemap.
|
||||
// One problem is that the old node dependencies point to nodes in the old sequencer.
|
||||
// One problem is that the old node dependencies point to nodes in the old AnimatorSet.
|
||||
// We need to track the old/new nodes in order to reconstruct the dependencies in the clone.
|
||||
HashMap<Node, Node> nodeCloneMap = new HashMap<Node, Node>(); // <old, new>
|
||||
for (Node node : mNodes) {
|
||||
@@ -441,21 +437,21 @@ public final class Sequencer extends Animatable {
|
||||
nodeClone.tmpDependencies = null;
|
||||
nodeClone.nodeDependents = null;
|
||||
nodeClone.nodeDependencies = null;
|
||||
// clear out any listeners that were set up by the sequencer; these will
|
||||
// clear out any listeners that were set up by the AnimatorSet; these will
|
||||
// be set up when the clone's nodes are sorted
|
||||
ArrayList<AnimatableListener> cloneListeners = nodeClone.animation.getListeners();
|
||||
ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners();
|
||||
if (cloneListeners != null) {
|
||||
ArrayList<AnimatableListener> listenersToRemove = null;
|
||||
for (AnimatableListener listener : cloneListeners) {
|
||||
if (listener instanceof SequencerAnimatableListener) {
|
||||
ArrayList<AnimatorListener> listenersToRemove = null;
|
||||
for (AnimatorListener listener : cloneListeners) {
|
||||
if (listener instanceof AnimatorSetListener) {
|
||||
if (listenersToRemove == null) {
|
||||
listenersToRemove = new ArrayList<AnimatableListener>();
|
||||
listenersToRemove = new ArrayList<AnimatorListener>();
|
||||
}
|
||||
listenersToRemove.add(listener);
|
||||
}
|
||||
}
|
||||
if (listenersToRemove != null) {
|
||||
for (AnimatableListener listener : listenersToRemove) {
|
||||
for (AnimatorListener listener : listenersToRemove) {
|
||||
cloneListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
@@ -483,9 +479,9 @@ public final class Sequencer extends Animatable {
|
||||
* animations. If an animation has multiple dependencies on other animations, then
|
||||
* all dependencies must be satisfied before the animation is started.
|
||||
*/
|
||||
private static class DependencyListener implements AnimatableListener {
|
||||
private static class DependencyListener implements AnimatorListener {
|
||||
|
||||
private Sequencer mSequencer;
|
||||
private AnimatorSet mAnimatorSet;
|
||||
|
||||
// The node upon which the dependency is based.
|
||||
private Node mNode;
|
||||
@@ -494,8 +490,8 @@ public final class Sequencer extends Animatable {
|
||||
// the node
|
||||
private int mRule;
|
||||
|
||||
public DependencyListener(Sequencer sequencer, Node node, int rule) {
|
||||
this.mSequencer = sequencer;
|
||||
public DependencyListener(AnimatorSet animatorSet, Node node, int rule) {
|
||||
this.mAnimatorSet = animatorSet;
|
||||
this.mNode = node;
|
||||
this.mRule = rule;
|
||||
}
|
||||
@@ -505,13 +501,13 @@ public final class Sequencer extends Animatable {
|
||||
* to prevent follow-on animations from running when some dependency
|
||||
* animation is canceled.
|
||||
*/
|
||||
public void onAnimationCancel(Animatable animation) {
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An end event is received - see if this is an event we are listening for
|
||||
*/
|
||||
public void onAnimationEnd(Animatable animation) {
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mRule == Dependency.AFTER) {
|
||||
startIfReady(animation);
|
||||
}
|
||||
@@ -520,13 +516,13 @@ public final class Sequencer extends Animatable {
|
||||
/**
|
||||
* Ignore repeat events for now
|
||||
*/
|
||||
public void onAnimationRepeat(Animatable animation) {
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A start event is received - see if this is an event we are listening for
|
||||
*/
|
||||
public void onAnimationStart(Animatable animation) {
|
||||
public void onAnimationStart(Animator animation) {
|
||||
if (mRule == Dependency.WITH) {
|
||||
startIfReady(animation);
|
||||
}
|
||||
@@ -538,9 +534,9 @@ public final class Sequencer extends Animatable {
|
||||
* the animation.
|
||||
* @param dependencyAnimation the animation that sent the event.
|
||||
*/
|
||||
private void startIfReady(Animatable dependencyAnimation) {
|
||||
if (mSequencer.mCanceled) {
|
||||
// if the parent Sequencer was canceled, then don't start any dependent anims
|
||||
private void startIfReady(Animator dependencyAnimation) {
|
||||
if (mAnimatorSet.mCanceled) {
|
||||
// if the parent AnimatorSet was canceled, then don't start any dependent anims
|
||||
return;
|
||||
}
|
||||
Dependency dependencyToRemove = null;
|
||||
@@ -558,37 +554,37 @@ public final class Sequencer extends Animatable {
|
||||
if (mNode.tmpDependencies.size() == 0) {
|
||||
// all dependencies satisfied: start the animation
|
||||
mNode.animation.start();
|
||||
mSequencer.mPlayingSet.add(mNode.animation);
|
||||
mAnimatorSet.mPlayingSet.add(mNode.animation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SequencerAnimatableListener implements AnimatableListener {
|
||||
private class AnimatorSetListener implements AnimatorListener {
|
||||
|
||||
private Sequencer mSequencer;
|
||||
private AnimatorSet mAnimatorSet;
|
||||
|
||||
SequencerAnimatableListener(Sequencer sequencer) {
|
||||
mSequencer = sequencer;
|
||||
AnimatorSetListener(AnimatorSet animatorSet) {
|
||||
mAnimatorSet = animatorSet;
|
||||
}
|
||||
|
||||
public void onAnimationCancel(Animatable animation) {
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
if (mPlayingSet.size() == 0) {
|
||||
if (mListeners != null) {
|
||||
for (AnimatableListener listener : mListeners) {
|
||||
listener.onAnimationCancel(mSequencer);
|
||||
for (AnimatorListener listener : mListeners) {
|
||||
listener.onAnimationCancel(mAnimatorSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onAnimationEnd(Animatable animation) {
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
animation.removeListener(this);
|
||||
mPlayingSet.remove(animation);
|
||||
Node animNode = mSequencer.mNodeMap.get(animation);
|
||||
Node animNode = mAnimatorSet.mNodeMap.get(animation);
|
||||
animNode.done = true;
|
||||
ArrayList<Node> sortedNodes = mSequencer.mSortedNodes;
|
||||
ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
|
||||
boolean allDone = true;
|
||||
for (Node node : sortedNodes) {
|
||||
if (!node.done) {
|
||||
@@ -598,23 +594,23 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
if (allDone) {
|
||||
// If this was the last child animation to end, then notify listeners that this
|
||||
// sequencer has ended
|
||||
// AnimatorSet has ended
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatableListener> tmpListeners =
|
||||
(ArrayList<AnimatableListener>) mListeners.clone();
|
||||
for (AnimatableListener listener : tmpListeners) {
|
||||
listener.onAnimationEnd(mSequencer);
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationEnd(mAnimatorSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
public void onAnimationRepeat(Animatable animation) {
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
|
||||
// Nothing to do
|
||||
public void onAnimationStart(Animatable animation) {
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -658,7 +654,7 @@ public final class Sequencer extends Animatable {
|
||||
mNeedsSort = false;
|
||||
if (mSortedNodes.size() != mNodes.size()) {
|
||||
throw new IllegalStateException("Circular dependencies cannot exist"
|
||||
+ " in Sequencer");
|
||||
+ " in AnimatorSet");
|
||||
}
|
||||
} else {
|
||||
// Doesn't need sorting, but still need to add in the nodeDependencies list
|
||||
@@ -702,13 +698,13 @@ public final class Sequencer extends Animatable {
|
||||
}
|
||||
|
||||
/**
|
||||
* A Node is an embodiment of both the Animatable that it wraps as well as
|
||||
* A Node is an embodiment of both the Animator that it wraps as well as
|
||||
* any dependencies that are associated with that Animation. This includes
|
||||
* both dependencies upon other nodes (in the dependencies list) as
|
||||
* well as dependencies of other nodes upon this (in the nodeDependents list).
|
||||
*/
|
||||
private static class Node implements Cloneable {
|
||||
public Animatable animation;
|
||||
public Animator animation;
|
||||
|
||||
/**
|
||||
* These are the dependencies that this node's animation has on other
|
||||
@@ -723,8 +719,8 @@ public final class Sequencer extends Animatable {
|
||||
* But we also use the list to keep track of when multiple dependencies are satisfied,
|
||||
* but removing each dependency as it is satisfied. We do not want to remove
|
||||
* the dependency itself from the list, because we need to retain that information
|
||||
* if the sequencer is launched in the future. So we create a copy of the dependency
|
||||
* list when the sequencer starts and use this tmpDependencies list to track the
|
||||
* if the AnimatorSet is launched in the future. So we create a copy of the dependency
|
||||
* list when the AnimatorSet starts and use this tmpDependencies list to track the
|
||||
* list of satisfied dependencies.
|
||||
*/
|
||||
public ArrayList<Dependency> tmpDependencies = null;
|
||||
@@ -744,8 +740,8 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Flag indicating whether the animation in this node is finished. This flag
|
||||
* is used by Sequencer to check, as each animation ends, whether all child animations
|
||||
* are done and it's time to send out an end event for the entire Sequencer.
|
||||
* is used by AnimatorSet to check, as each animation ends, whether all child animations
|
||||
* are done and it's time to send out an end event for the entire AnimatorSet.
|
||||
*/
|
||||
public boolean done = false;
|
||||
|
||||
@@ -756,7 +752,7 @@ public final class Sequencer extends Animatable {
|
||||
*
|
||||
* @param animation The animation that the Node encapsulates.
|
||||
*/
|
||||
public Node(Animatable animation) {
|
||||
public Node(Animator animation) {
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
@@ -785,7 +781,7 @@ public final class Sequencer extends Animatable {
|
||||
public Node clone() {
|
||||
try {
|
||||
Node node = (Node) super.clone();
|
||||
node.animation = (Animatable) animation.clone();
|
||||
node.animation = (Animator) animation.clone();
|
||||
return node;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
@@ -795,45 +791,45 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* The <code>Builder</code> object is a utility class to facilitate adding animations to a
|
||||
* <code>Sequencer</code> along with the relationships between the various animations. The
|
||||
* <code>AnimatorSet</code> along with the relationships between the various animations. The
|
||||
* intention of the <code>Builder</code> methods, along with the {@link
|
||||
* Sequencer#play(Animatable) play()} method of <code>Sequencer</code> is to make it possible to
|
||||
* AnimatorSet#play(Animator) play()} method of <code>AnimatorSet</code> is to make it possible to
|
||||
* express the dependency relationships of animations in a natural way. Developers can also use
|
||||
* the {@link Sequencer#playTogether(Animatable[]) playTogether()} and {@link
|
||||
* Sequencer#playSequentially(Animatable[]) playSequentially()} methods if these suit the need,
|
||||
* but it might be easier in some situations to express the sequence of animations in pairs.
|
||||
* the {@link AnimatorSet#playTogether(Animator[]) playTogether()} and {@link
|
||||
* AnimatorSet#playSequentially(Animator[]) playSequentially()} methods if these suit the need,
|
||||
* but it might be easier in some situations to express the AnimatorSet of animations in pairs.
|
||||
* <p/>
|
||||
* <p>The <code>Builder</code> object cannot be constructed directly, but is rather constructed
|
||||
* internally via a call to {@link Sequencer#play(Animatable)}.</p>
|
||||
* internally via a call to {@link AnimatorSet#play(Animator)}.</p>
|
||||
* <p/>
|
||||
* <p>For example, this sets up a Sequencer to play anim1 and anim2 at the same time, anim3 to
|
||||
* <p>For example, this sets up a AnimatorSet to play anim1 and anim2 at the same time, anim3 to
|
||||
* play when anim2 finishes, and anim4 to play when anim3 finishes:</p>
|
||||
* <pre>
|
||||
* Sequencer s = new Sequencer();
|
||||
* AnimatorSet s = new AnimatorSet();
|
||||
* s.play(anim1).with(anim2);
|
||||
* s.play(anim2).before(anim3);
|
||||
* s.play(anim4).after(anim3);
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>Note in the example that both {@link Builder#before(Animatable)} and {@link
|
||||
* Builder#after(Animatable)} are used. These are just different ways of expressing the same
|
||||
* <p>Note in the example that both {@link Builder#before(Animator)} and {@link
|
||||
* Builder#after(Animator)} are used. These are just different ways of expressing the same
|
||||
* relationship and are provided to make it easier to say things in a way that is more natural,
|
||||
* depending on the situation.</p>
|
||||
* <p/>
|
||||
* <p>It is possible to make several calls into the same <code>Builder</code> object to express
|
||||
* multiple relationships. However, note that it is only the animation passed into the initial
|
||||
* {@link Sequencer#play(Animatable)} method that is the dependency in any of the successive
|
||||
* {@link AnimatorSet#play(Animator)} method that is the dependency in any of the successive
|
||||
* calls to the <code>Builder</code> object. For example, the following code starts both anim2
|
||||
* and anim3 when anim1 ends; there is no direct dependency relationship between anim2 and
|
||||
* anim3:
|
||||
* <pre>
|
||||
* Sequencer s = new Sequencer();
|
||||
* AnimatorSet s = new AnimatorSet();
|
||||
* s.play(anim1).before(anim2).before(anim3);
|
||||
* </pre>
|
||||
* If the desired result is to play anim1 then anim2 then anim3, this code expresses the
|
||||
* relationship correctly:</p>
|
||||
* <pre>
|
||||
* Sequencer s = new Sequencer();
|
||||
* AnimatorSet s = new AnimatorSet();
|
||||
* s.play(anim1).before(anim2);
|
||||
* s.play(anim2).before(anim3);
|
||||
* </pre>
|
||||
@@ -841,26 +837,26 @@ public final class Sequencer extends Animatable {
|
||||
* <p>Note that it is possible to express relationships that cannot be resolved and will not
|
||||
* result in sensible results. For example, <code>play(anim1).after(anim1)</code> makes no
|
||||
* sense. In general, circular dependencies like this one (or more indirect ones where a depends
|
||||
* on b, which depends on c, which depends on a) should be avoided. Only create sequences that
|
||||
* can boil down to a simple, one-way relationship of animations starting with, before, and
|
||||
* on b, which depends on c, which depends on a) should be avoided. Only create AnimatorSets
|
||||
* that can boil down to a simple, one-way relationship of animations starting with, before, and
|
||||
* after other, different, animations.</p>
|
||||
*/
|
||||
public class Builder {
|
||||
|
||||
/**
|
||||
* This tracks the current node being processed. It is supplied to the play() method
|
||||
* of Sequencer and passed into the constructor of Builder.
|
||||
* of AnimatorSet and passed into the constructor of Builder.
|
||||
*/
|
||||
private Node mCurrentNode;
|
||||
|
||||
/**
|
||||
* package-private constructor. Builders are only constructed by Sequencer, when the
|
||||
* package-private constructor. Builders are only constructed by AnimatorSet, when the
|
||||
* play() method is called.
|
||||
*
|
||||
* @param anim The animation that is the dependency for the other animations passed into
|
||||
* the other methods of this Builder object.
|
||||
*/
|
||||
Builder(Animatable anim) {
|
||||
Builder(Animator anim) {
|
||||
mCurrentNode = mNodeMap.get(anim);
|
||||
if (mCurrentNode == null) {
|
||||
mCurrentNode = new Node(anim);
|
||||
@@ -871,12 +867,12 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Sets up the given animation to play at the same time as the animation supplied in the
|
||||
* {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object.
|
||||
* {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object.
|
||||
*
|
||||
* @param anim The animation that will play when the animation supplied to the
|
||||
* {@link Sequencer#play(Animatable)} method starts.
|
||||
* {@link AnimatorSet#play(Animator)} method starts.
|
||||
*/
|
||||
public void with(Animatable anim) {
|
||||
public void with(Animator anim) {
|
||||
Node node = mNodeMap.get(anim);
|
||||
if (node == null) {
|
||||
node = new Node(anim);
|
||||
@@ -889,13 +885,13 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Sets up the given animation to play when the animation supplied in the
|
||||
* {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
|
||||
* {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
|
||||
* ends.
|
||||
*
|
||||
* @param anim The animation that will play when the animation supplied to the
|
||||
* {@link Sequencer#play(Animatable)} method ends.
|
||||
* {@link AnimatorSet#play(Animator)} method ends.
|
||||
*/
|
||||
public void before(Animatable anim) {
|
||||
public void before(Animator anim) {
|
||||
Node node = mNodeMap.get(anim);
|
||||
if (node == null) {
|
||||
node = new Node(anim);
|
||||
@@ -908,13 +904,13 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Sets up the given animation to play when the animation supplied in the
|
||||
* {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
|
||||
* {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
|
||||
* to start when the animation supplied in this method call ends.
|
||||
*
|
||||
* @param anim The animation whose end will cause the animation supplied to the
|
||||
* {@link Sequencer#play(Animatable)} method to play.
|
||||
* {@link AnimatorSet#play(Animator)} method to play.
|
||||
*/
|
||||
public void after(Animatable anim) {
|
||||
public void after(Animator anim) {
|
||||
Node node = mNodeMap.get(anim);
|
||||
if (node == null) {
|
||||
node = new Node(anim);
|
||||
@@ -927,15 +923,15 @@ public final class Sequencer extends Animatable {
|
||||
|
||||
/**
|
||||
* Sets up the animation supplied in the
|
||||
* {@link Sequencer#play(Animatable)} call that created this <code>Builder</code> object
|
||||
* {@link AnimatorSet#play(Animator)} call that created this <code>Builder</code> object
|
||||
* to play when the given amount of time elapses.
|
||||
*
|
||||
* @param delay The number of milliseconds that should elapse before the
|
||||
* animation starts.
|
||||
*/
|
||||
public void after(long delay) {
|
||||
// setup dummy Animator just to run the clock
|
||||
after(new Animator(delay, 0f, 1f));
|
||||
// setup dummy ValueAnimator just to run the clock
|
||||
after(new ValueAnimator(delay, 0f, 1f));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* This class holds a time/value pair for an animation. The Keyframe class is used
|
||||
* by {@link Animator} to define the values that the animation target will have over the course
|
||||
* by {@link ValueAnimator} to define the values that the animation target will have over the course
|
||||
* of the animation. As the time proceeds from one keyframe to the other, the value of the
|
||||
* target object will animate between the value at the previous keyframe and the value at the
|
||||
* next keyframe. Each keyframe also holds an option {@link android.view.animation.Interpolator}
|
||||
@@ -59,7 +59,7 @@ public class Keyframe implements Cloneable {
|
||||
* the time in this keyframe, and the the value animated from as the time passes the time in
|
||||
* this keyframe.
|
||||
* @param valueType The type of the <code>value</code> object. This is used by the
|
||||
* {@link #getValue()} functionm, which is queried by {@link Animator} to determine
|
||||
* {@link #getValue()} functionm, which is queried by {@link ValueAnimator} to determine
|
||||
* the type of {@link TypeEvaluator} to use to interpolate between values.
|
||||
*/
|
||||
private Keyframe(float fraction, Object value, Class valueType) {
|
||||
@@ -239,7 +239,7 @@ public class Keyframe implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of keyframe. This information is used by Animator to determine the type of
|
||||
* Gets the type of keyframe. This information is used by ValueAnimator to determine the type of
|
||||
* {@link TypeEvaluator} to use when calculating values between keyframes. The type is based
|
||||
* on the type of Keyframe created.
|
||||
*
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.ArrayList;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* This class holds a collection of Keyframe objects and is called by Animator to calculate
|
||||
* This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
|
||||
* values between those keyframes for a given animation. The class internal to the animation
|
||||
* package because it is an implementation detail of how Keyframes are stored and used.
|
||||
*/
|
||||
|
||||
@@ -32,8 +32,8 @@ import java.util.List;
|
||||
* transitions for a layout container, create a LayoutTransition object and set it on any
|
||||
* ViewGroup by calling {@link ViewGroup#setLayoutTransition(LayoutTransition)}. This will cause
|
||||
* default animations to run whenever items are added to or removed from that container. To specify
|
||||
* custom animations, use the {@link LayoutTransition#setAnimatable(int, Animatable)
|
||||
* setAnimatable()} method.
|
||||
* custom animations, use the {@link LayoutTransition#setAnimator(int, Animator)
|
||||
* setAnimator()} method.
|
||||
*
|
||||
* <p>One of the core concepts of these transition animations is that there are two core
|
||||
* changes that cause the transition and four different animations that run because of
|
||||
@@ -61,7 +61,7 @@ import java.util.List;
|
||||
* CHANGE_APPEARING animation animates <code>left</code>, <code>top</code>, <code>right</code>,
|
||||
* and <code>bottom</code>. Values for these properties are updated with the pre- and post-layout
|
||||
* values when the transition begins. Custom animations will be similarly populated with
|
||||
* the target and values being animated, assuming they use PropertyAnimator objects with
|
||||
* the target and values being animated, assuming they use ObjectAnimator objects with
|
||||
* property names that are known on the target object.</p>
|
||||
*/
|
||||
public class LayoutTransition {
|
||||
@@ -93,21 +93,21 @@ public class LayoutTransition {
|
||||
/**
|
||||
* These variables hold the animations that are currently used to run the transition effects.
|
||||
* These animations are set to defaults, but can be changed to custom animations by
|
||||
* calls to setAnimatable().
|
||||
* calls to setAnimator().
|
||||
*/
|
||||
private Animatable mDisappearingAnim = null;
|
||||
private Animatable mAppearingAnim = null;
|
||||
private Animatable mChangingAppearingAnim = null;
|
||||
private Animatable mChangingDisappearingAnim = null;
|
||||
private Animator mDisappearingAnim = null;
|
||||
private Animator mAppearingAnim = null;
|
||||
private Animator mChangingAppearingAnim = null;
|
||||
private Animator mChangingDisappearingAnim = null;
|
||||
|
||||
/**
|
||||
* These are the default animations, defined in the constructor, that will be used
|
||||
* unless the user specifies custom animations.
|
||||
*/
|
||||
private static PropertyAnimator defaultChangeIn;
|
||||
private static PropertyAnimator defaultChangeOut;
|
||||
private static PropertyAnimator defaultFadeIn;
|
||||
private static PropertyAnimator defaultFadeOut;
|
||||
private static ObjectAnimator defaultChangeIn;
|
||||
private static ObjectAnimator defaultChangeOut;
|
||||
private static ObjectAnimator defaultFadeIn;
|
||||
private static ObjectAnimator defaultFadeOut;
|
||||
|
||||
/**
|
||||
* The default duration used by all animations.
|
||||
@@ -154,7 +154,7 @@ public class LayoutTransition {
|
||||
* we cache all of the current animations in this map for possible cancellation on
|
||||
* another layout event.
|
||||
*/
|
||||
private HashMap<View, Animatable> currentAnimations = new HashMap<View, Animatable>();
|
||||
private HashMap<View, Animator> currentAnimations = new HashMap<View, Animator>();
|
||||
|
||||
/**
|
||||
* This hashmap is used to track the listeners that have been added to the children of
|
||||
@@ -194,7 +194,7 @@ public class LayoutTransition {
|
||||
PropertyValuesHolder<Integer> pvhTop = new PropertyValuesHolder<Integer>("top", 0, 1);
|
||||
PropertyValuesHolder<Integer> pvhRight = new PropertyValuesHolder<Integer>("right", 0, 1);
|
||||
PropertyValuesHolder<Integer> pvhBottom = new PropertyValuesHolder<Integer>("bottom", 0, 1);
|
||||
defaultChangeIn = new PropertyAnimator<PropertyValuesHolder>(DEFAULT_DURATION, this,
|
||||
defaultChangeIn = new ObjectAnimator<PropertyValuesHolder>(DEFAULT_DURATION, this,
|
||||
pvhLeft, pvhTop, pvhRight, pvhBottom);
|
||||
defaultChangeIn.setStartDelay(mChangingAppearingDelay);
|
||||
defaultChangeIn.setInterpolator(mChangingAppearingInterpolator);
|
||||
@@ -202,11 +202,11 @@ public class LayoutTransition {
|
||||
defaultChangeOut.setStartDelay(mChangingDisappearingDelay);
|
||||
defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator);
|
||||
defaultFadeIn =
|
||||
new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 0f, 1f);
|
||||
new ObjectAnimator<Float>(DEFAULT_DURATION, this, "alpha", 0f, 1f);
|
||||
defaultFadeIn.setStartDelay(mAppearingDelay);
|
||||
defaultFadeIn.setInterpolator(mAppearingInterpolator);
|
||||
defaultFadeOut =
|
||||
new PropertyAnimator<Float>(DEFAULT_DURATION, this, "alpha", 1f, 0f);
|
||||
new ObjectAnimator<Float>(DEFAULT_DURATION, this, "alpha", 1f, 0f);
|
||||
defaultFadeOut.setStartDelay(mDisappearingDelay);
|
||||
defaultFadeOut.setInterpolator(mDisappearingInterpolator);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
|
||||
* delay is being set.
|
||||
* @param delay The length of time, in milliseconds, to delay before starting the animation.
|
||||
* @see android.animation.Animatable#setStartDelay(long)
|
||||
* @see Animator#setStartDelay(long)
|
||||
*/
|
||||
public void setStartDelay(int transitionType, long delay) {
|
||||
switch (transitionType) {
|
||||
@@ -268,7 +268,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose start
|
||||
* delay is returned.
|
||||
* @return long The start delay of the specified animation.
|
||||
* @see android.animation.Animatable#getStartDelay()
|
||||
* @see Animator#getStartDelay()
|
||||
*/
|
||||
public long getStartDelay(int transitionType) {
|
||||
switch (transitionType) {
|
||||
@@ -294,7 +294,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is being set.
|
||||
* @param duration The length of time, in milliseconds, that the specified animation should run.
|
||||
* @see android.animation.Animatable#setDuration(long)
|
||||
* @see Animator#setDuration(long)
|
||||
*/
|
||||
public void setDuration(int transitionType, long duration) {
|
||||
switch (transitionType) {
|
||||
@@ -322,7 +322,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is returned.
|
||||
* @return long The duration of the specified animation.
|
||||
* @see android.animation.Animatable#getDuration()
|
||||
* @see Animator#getDuration()
|
||||
*/
|
||||
public long getDuration(int transitionType) {
|
||||
switch (transitionType) {
|
||||
@@ -387,7 +387,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is being set.
|
||||
* @param interpolator The interpolator that the specified animation should use.
|
||||
* @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
|
||||
* @see Animator#setInterpolator(android.view.animation.Interpolator)
|
||||
*/
|
||||
public void setInterpolator(int transitionType, Interpolator interpolator) {
|
||||
switch (transitionType) {
|
||||
@@ -415,7 +415,7 @@ public class LayoutTransition {
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is being set.
|
||||
* @return Interpolator The interpolator that the specified animation uses.
|
||||
* @see android.animation.Animatable#setInterpolator(android.view.animation.Interpolator)
|
||||
* @see Animator#setInterpolator(android.view.animation.Interpolator)
|
||||
*/
|
||||
public Interpolator getInterpolator(int transitionType) {
|
||||
switch (transitionType) {
|
||||
@@ -434,11 +434,11 @@ public class LayoutTransition {
|
||||
|
||||
/**
|
||||
* Sets the animation used during one of the transition types that may run. Any
|
||||
* Animatable object can be used, but to be most useful in the context of layout
|
||||
* transitions, the animation should either be a PropertyAnimator or a Sequencer
|
||||
* of animations including PropertyAnimators. Also, these PropertyAnimator objects
|
||||
* Animator object can be used, but to be most useful in the context of layout
|
||||
* transitions, the animation should either be a ObjectAnimator or a AnimatorSet
|
||||
* of animations including PropertyAnimators. Also, these ObjectAnimator objects
|
||||
* should be able to get and set values on their target objects automatically. For
|
||||
* example, a PropertyAnimator that animates the property "left" is able to set and get the
|
||||
* example, a ObjectAnimator that animates the property "left" is able to set and get the
|
||||
* <code>left</code> property from the View objects being animated by the layout
|
||||
* transition. The transition works by setting target objects and properties
|
||||
* dynamically, according to the pre- and post-layoout values of those objects, so
|
||||
@@ -454,26 +454,26 @@ public class LayoutTransition {
|
||||
* object (presumably 1) as its starting and ending value when the animation begins.
|
||||
* Animations which need to use values at the beginning and end that may not match the
|
||||
* values queried when the transition begins may need to use a different mechanism
|
||||
* than a standard PropertyAnimator object.</p>
|
||||
* than a standard ObjectAnimator object.</p>
|
||||
*
|
||||
* @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is being set.
|
||||
* @param animatable The animation being assigned.
|
||||
* @param animator The animation being assigned.
|
||||
*/
|
||||
public void setAnimatable(int transitionType, Animatable animatable) {
|
||||
public void setAnimator(int transitionType, Animator animator) {
|
||||
switch (transitionType) {
|
||||
case CHANGE_APPEARING:
|
||||
mChangingAppearingAnim = (animatable != null) ? animatable : defaultChangeIn;
|
||||
mChangingAppearingAnim = (animator != null) ? animator : defaultChangeIn;
|
||||
break;
|
||||
case CHANGE_DISAPPEARING:
|
||||
mChangingDisappearingAnim = (animatable != null) ? animatable : defaultChangeOut;
|
||||
mChangingDisappearingAnim = (animator != null) ? animator : defaultChangeOut;
|
||||
break;
|
||||
case APPEARING:
|
||||
mAppearingAnim = (animatable != null) ? animatable : defaultFadeIn;
|
||||
mAppearingAnim = (animator != null) ? animator : defaultFadeIn;
|
||||
break;
|
||||
case DISAPPEARING:
|
||||
mDisappearingAnim = (animatable != null) ? animatable : defaultFadeOut;
|
||||
mDisappearingAnim = (animator != null) ? animator : defaultFadeOut;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -484,10 +484,10 @@ public class LayoutTransition {
|
||||
* @param transitionType one of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
|
||||
* {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the animation whose
|
||||
* duration is being set.
|
||||
* @return Animatable The animation being used for the given transition type.
|
||||
* @see #setAnimatable(int, Animatable)
|
||||
* @return Animator The animation being used for the given transition type.
|
||||
* @see #setAnimator(int, Animator)
|
||||
*/
|
||||
public Animatable getAnimatable(int transitionType) {
|
||||
public Animator getAnimator(int transitionType) {
|
||||
switch (transitionType) {
|
||||
case CHANGE_APPEARING:
|
||||
return mChangingAppearingAnim;
|
||||
@@ -529,21 +529,21 @@ public class LayoutTransition {
|
||||
if (child != newView) {
|
||||
|
||||
// If there's an animation running on this view already, cancel it
|
||||
Animatable currentAnimation = currentAnimations.get(child);
|
||||
Animator currentAnimation = currentAnimations.get(child);
|
||||
if (currentAnimation != null) {
|
||||
currentAnimation.cancel();
|
||||
currentAnimations.remove(child);
|
||||
}
|
||||
|
||||
// Make a copy of the appropriate animation
|
||||
final Animatable anim = (changeReason == APPEARING) ?
|
||||
final Animator anim = (changeReason == APPEARING) ?
|
||||
mChangingAppearingAnim.clone() :
|
||||
mChangingDisappearingAnim.clone();
|
||||
|
||||
// Set the target object for the animation
|
||||
anim.setTarget(child);
|
||||
|
||||
// A PropertyAnimator (or Sequencer of them) can extract start values from
|
||||
// A ObjectAnimator (or AnimatorSet of them) can extract start values from
|
||||
// its target object
|
||||
anim.setupStartValues();
|
||||
|
||||
@@ -574,20 +574,20 @@ public class LayoutTransition {
|
||||
anim.setDuration(duration);
|
||||
|
||||
// Remove the animation from the cache when it ends
|
||||
anim.addListener(new AnimatableListenerAdapter() {
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
private boolean canceled = false;
|
||||
public void onAnimationCancel(Animatable animatable) {
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
// we remove canceled animations immediately, not here
|
||||
canceled = true;
|
||||
}
|
||||
public void onAnimationEnd(Animatable animatable) {
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
if (!canceled) {
|
||||
currentAnimations.remove(child);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator) anim).setCurrentPlayTime(0);
|
||||
if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator) anim).setCurrentPlayTime(0);
|
||||
}
|
||||
anim.start();
|
||||
|
||||
@@ -626,15 +626,15 @@ public class LayoutTransition {
|
||||
* @param child The View being added to the ViewGroup.
|
||||
*/
|
||||
private void runAppearingTransition(final ViewGroup parent, final View child) {
|
||||
Animatable anim = mAppearingAnim.clone();
|
||||
Animator anim = mAppearingAnim.clone();
|
||||
anim.setTarget(child);
|
||||
anim.setStartDelay(mAppearingDelay);
|
||||
anim.setDuration(mAppearingDuration);
|
||||
if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator) anim).setCurrentPlayTime(0);
|
||||
if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator) anim).setCurrentPlayTime(0);
|
||||
}
|
||||
if (mListeners != null) {
|
||||
anim.addListener(new AnimatableListenerAdapter() {
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
public void onAnimationEnd() {
|
||||
for (TransitionListener listener : mListeners) {
|
||||
listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
|
||||
@@ -652,12 +652,12 @@ public class LayoutTransition {
|
||||
* @param child The View being removed from the ViewGroup.
|
||||
*/
|
||||
private void runDisappearingTransition(final ViewGroup parent, final View child) {
|
||||
Animatable anim = mDisappearingAnim.clone();
|
||||
Animator anim = mDisappearingAnim.clone();
|
||||
anim.setStartDelay(mDisappearingDelay);
|
||||
anim.setDuration(mDisappearingDuration);
|
||||
anim.setTarget(child);
|
||||
if (mListeners != null) {
|
||||
anim.addListener(new AnimatableListenerAdapter() {
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
public void onAnimationEnd() {
|
||||
for (TransitionListener listener : mListeners) {
|
||||
listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
|
||||
@@ -665,8 +665,8 @@ public class LayoutTransition {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator) anim).setCurrentPlayTime(0);
|
||||
if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator) anim).setCurrentPlayTime(0);
|
||||
}
|
||||
anim.start();
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ import android.util.Log;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* This subclass of {@link Animator} provides support for animating properties on target objects.
|
||||
* This subclass of {@link ValueAnimator} provides support for animating properties on target objects.
|
||||
* The constructors of this class take parameters to define the target object that will be animated
|
||||
* as well as the name of the property that will be animated. Appropriate set/get functions
|
||||
* are then determined internally and the animation will call these functions as necessary to
|
||||
* animate the property.
|
||||
*/
|
||||
public final class PropertyAnimator<T> extends Animator<T> {
|
||||
public final class ObjectAnimator<T> extends ValueAnimator<T> {
|
||||
|
||||
// The target object on which the property exists, set in the constructor
|
||||
private Object mTarget;
|
||||
@@ -47,7 +47,7 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
* <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
|
||||
* the setter function will fail.</p>
|
||||
*
|
||||
* <p>If this PropertyAnimator has been set up to animate several properties together,
|
||||
* <p>If this ObjectAnimator has been set up to animate several properties together,
|
||||
* using more than one PropertyValuesHolder objects, then setting the propertyName simply
|
||||
* sets the propertyName in the first of those PropertyValuesHolder objects.</p>
|
||||
*
|
||||
@@ -101,18 +101,18 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
try {
|
||||
returnVal = mTarget.getClass().getMethod(setterName, args);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e("PropertyAnimator",
|
||||
Log.e("ObjectAnimator",
|
||||
"Couldn't find setter/getter for property " + mPropertyName + ": " + e);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PropertyAnimator object. This default constructor is primarily for
|
||||
* Creates a new ObjectAnimator object. This default constructor is primarily for
|
||||
* use internally; the other constructors which take parameters are more generally
|
||||
* useful.
|
||||
*/
|
||||
public PropertyAnimator() {
|
||||
public ObjectAnimator() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +128,7 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
* is assumed to be the final value being animated to, and the initial value will be
|
||||
* derived on the fly.
|
||||
*/
|
||||
public PropertyAnimator(long duration, Object target, String propertyName, T...values) {
|
||||
public ObjectAnimator(long duration, Object target, String propertyName, T...values) {
|
||||
super(duration, (T[]) values);
|
||||
mTarget = target;
|
||||
setPropertyName(propertyName);
|
||||
@@ -136,7 +136,7 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>PropertyValueHolder</code> values. This constructor should
|
||||
* be used when animating several properties at once with the same PropertyAnimator, since
|
||||
* be used when animating several properties at once with the same ObjectAnimator, since
|
||||
* PropertyValuesHolder allows you to associate a set of animation values with a property
|
||||
* name.
|
||||
*
|
||||
@@ -148,7 +148,7 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
* @param values The PropertyValuesHolder objects which hold each the property name and values
|
||||
* to animate that property between.
|
||||
*/
|
||||
public PropertyAnimator(long duration, Object target, PropertyValuesHolder...values) {
|
||||
public ObjectAnimator(long duration, Object target, PropertyValuesHolder...values) {
|
||||
super(duration);
|
||||
setValues(values);
|
||||
mTarget = target;
|
||||
@@ -239,8 +239,8 @@ public final class PropertyAnimator<T> extends Animator<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyAnimator clone() {
|
||||
final PropertyAnimator anim = (PropertyAnimator) super.clone();
|
||||
public ObjectAnimator clone() {
|
||||
final ObjectAnimator anim = (ObjectAnimator) super.clone();
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
@@ -27,31 +27,31 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
/**
|
||||
* This class holds information about a property and the values that that property
|
||||
* should take on during an animation. PropertyValuesHolder objects can be used to create
|
||||
* animations with Animator or PropertyAnimator that operate on several different properties
|
||||
* animations with ValueAnimator or ObjectAnimator that operate on several different properties
|
||||
* in parallel.
|
||||
*/
|
||||
public class PropertyValuesHolder<T> implements Cloneable {
|
||||
|
||||
/**
|
||||
* The name of the property associated with the values. This need not be a real property,
|
||||
* unless this object is being used with PropertyAnimator. But this is the name by which
|
||||
* aniamted values are looked up with getAnimatedValue(String) in Animator.
|
||||
* unless this object is being used with ObjectAnimator. But this is the name by which
|
||||
* aniamted values are looked up with getAnimatedValue(String) in ValueAnimator.
|
||||
*/
|
||||
private String mPropertyName;
|
||||
|
||||
/**
|
||||
* The setter function, if needed. PropertyAnimator hands off this functionality to
|
||||
* The setter function, if needed. ObjectAnimator hands off this functionality to
|
||||
* PropertyValuesHolder, since it holds all of the per-property information. This
|
||||
* property can be manually set via setSetter(). Otherwise, it is automatically
|
||||
* derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
|
||||
* derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
|
||||
*/
|
||||
private Method mSetter = null;
|
||||
|
||||
/**
|
||||
* The getter function, if needed. PropertyAnimator hands off this functionality to
|
||||
* The getter function, if needed. ObjectAnimator hands off this functionality to
|
||||
* PropertyValuesHolder, since it holds all of the per-property information. This
|
||||
* property can be manually set via setSetter(). Otherwise, it is automatically
|
||||
* derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
|
||||
* derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
|
||||
* The getter is only derived and used if one of the values is null.
|
||||
*/
|
||||
private Method mGetter = null;
|
||||
@@ -112,16 +112,16 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
|
||||
/**
|
||||
* The value most recently calculated by calculateValue(). This is set during
|
||||
* that function and might be retrieved later either by Animator.animatedValue() or
|
||||
* by the property-setting logic in PropertyAnimator.animatedValue().
|
||||
* that function and might be retrieved later either by ValueAnimator.animatedValue() or
|
||||
* by the property-setting logic in ObjectAnimator.animatedValue().
|
||||
*/
|
||||
private Object mAnimatedValue;
|
||||
|
||||
/**
|
||||
* Constructs a PropertyValuesHolder object with just a set of values. This constructor
|
||||
* is typically not used when animating objects with PropertyAnimator, because that
|
||||
* is typically not used when animating objects with ObjectAnimator, because that
|
||||
* object needs distinct and meaningful property names. Simpler animations of one
|
||||
* set of values using Animator may use this constructor, however, because no
|
||||
* set of values using ValueAnimator may use this constructor, however, because no
|
||||
* distinguishing name is needed.
|
||||
* @param values The set of values to animate between. If there is only one value, it
|
||||
* is assumed to be the final value being animated to, and the initial value will be
|
||||
@@ -141,14 +141,14 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
* on the object. Also, if any value is null, the value will be filled in when the animation
|
||||
* starts in the same way. This mechanism of automatically getting null values only works
|
||||
* if the PropertyValuesHolder object is used in conjunction
|
||||
* {@link android.animation.PropertyAnimator}, and with a getter function either
|
||||
* {@link ObjectAnimator}, and with a getter function either
|
||||
* derived automatically from <code>propertyName</code> or set explicitly via
|
||||
* {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
|
||||
* no way of determining what the value should be.
|
||||
* @param propertyName The name of the property associated with this set of values. This
|
||||
* can be the actual property name to be used when using a PropertyAnimator object, or
|
||||
* can be the actual property name to be used when using a ObjectAnimator object, or
|
||||
* just a name used to get animated values, such as if this object is used with an
|
||||
* Animator object.
|
||||
* ValueAnimator object.
|
||||
* @param values The set of values to animate between.
|
||||
*/
|
||||
public PropertyValuesHolder(String propertyName, T... values) {
|
||||
@@ -163,7 +163,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
* on the object. Also, if any value is null, the value will be filled in when the animation
|
||||
* starts in the same way. This mechanism of automatically getting null values only works
|
||||
* if the PropertyValuesHolder object is used in conjunction
|
||||
* {@link android.animation.PropertyAnimator}, and with a getter function either
|
||||
* {@link ObjectAnimator}, and with a getter function either
|
||||
* derived automatically from <code>propertyName</code> or set explicitly via
|
||||
* {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
|
||||
* no way of determining what the value should be.
|
||||
@@ -331,7 +331,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function (called from PropertyAnimator) to set up the setter and getter
|
||||
* Internal function (called from ObjectAnimator) to set up the setter and getter
|
||||
* prior to running the animation. If the setter has not been manually set for this
|
||||
* object, it will be derived automatically given the property name, target object, and
|
||||
* types of values supplied. If no getter has been set, it will be supplied iff any of the
|
||||
@@ -383,7 +383,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by PropertyAnimator when setting the start values for an animation.
|
||||
* This function is called by ObjectAnimator when setting the start values for an animation.
|
||||
* The start values are set according to the current values in the target object. The
|
||||
* property whose value is extracted is whatever is specified by the propertyName of this
|
||||
* PropertyValuesHolder object.
|
||||
@@ -395,7 +395,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by PropertyAnimator when setting the end values for an animation.
|
||||
* This function is called by ObjectAnimator when setting the end values for an animation.
|
||||
* The end values are set according to the current values in the target object. The
|
||||
* property whose value is extracted is whatever is specified by the propertyName of this
|
||||
* PropertyValuesHolder object.
|
||||
@@ -420,8 +420,8 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
/**
|
||||
* Internal function to set the value on the target object, using the setter set up
|
||||
* earlier on this PropertyValuesHolder object. This function is called by PropertyAnimator
|
||||
* to handle turning the value calculated by Animator into a value set on the object
|
||||
* earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
|
||||
* to handle turning the value calculated by ValueAnimator into a value set on the object
|
||||
* according to the name of the property.
|
||||
* @param target The target object on which the value is set
|
||||
*/
|
||||
@@ -439,7 +439,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function, called by Animator, to set up the TypeEvaluator that will be used
|
||||
* Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used
|
||||
* to calculate animated values.
|
||||
*/
|
||||
void init() {
|
||||
@@ -466,7 +466,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
|
||||
/**
|
||||
* Function used to calculate the value according to the evaluator set up for
|
||||
* this PropertyValuesHolder object. This function is called by Animator.animateValue().
|
||||
* this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue().
|
||||
*
|
||||
* @param fraction The elapsed, interpolated fraction of the animation.
|
||||
* @return The calculated value at this point in the animation.
|
||||
@@ -483,7 +483,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called with the animated values, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* to tell <code>ObjectAnimator</code> how to call that function simply through a property
|
||||
* name, so a setter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the setter function must take the same parameter type as the
|
||||
@@ -511,7 +511,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called to get an initial value, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* to tell <code>ObjectAnimator</code> how to call that function simply through a property
|
||||
* name, so a getter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the getter method is only called whether supplied here or derived
|
||||
@@ -569,7 +569,7 @@ public class PropertyValuesHolder<T> implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function, called by Animator and PropertyAnimator, to retrieve the value
|
||||
* Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value
|
||||
* most recently calculated in calculateValue().
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package android.animation;
|
||||
|
||||
/**
|
||||
* Interface for use with the {@link Animator#setEvaluator(TypeEvaluator)} function. Evaluators
|
||||
* Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators
|
||||
* allow developers to create animations on arbitrary property types, by allowing them to supply
|
||||
* custom evaulators for types that are not automatically understood and used by the animation
|
||||
* system.
|
||||
*
|
||||
* @see Animator#setEvaluator(TypeEvaluator)
|
||||
* @see ValueAnimator#setEvaluator(TypeEvaluator)
|
||||
*/
|
||||
public interface TypeEvaluator {
|
||||
|
||||
|
||||
972
core/java/android/animation/ValueAnimator.java
Executable file
972
core/java/android/animation/ValueAnimator.java
Executable file
@@ -0,0 +1,972 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.animation;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class provides a simple timing engine for running animations
|
||||
* which calculate animated values and set them on target objects.
|
||||
*
|
||||
* <p>There is a single timing pulse that all animations use. It runs in a
|
||||
* custom handler to ensure that property changes happen on the UI thread.</p>
|
||||
*
|
||||
* <p>By default, ValueAnimator uses non-linear time interpolation, via the
|
||||
* {@link AccelerateDecelerateInterpolator} class, which accelerates into and decelerates
|
||||
* out of an animation. This behavior can be changed by calling
|
||||
* {@link ValueAnimator#setInterpolator(Interpolator)}.</p>
|
||||
*/
|
||||
public class ValueAnimator<T> extends Animator {
|
||||
|
||||
/**
|
||||
* Internal constants
|
||||
*/
|
||||
|
||||
/*
|
||||
* The default amount of time in ms between animation frames
|
||||
*/
|
||||
private static final long DEFAULT_FRAME_DELAY = 30;
|
||||
|
||||
/**
|
||||
* Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent
|
||||
* by the handler to itself to process the next animation frame
|
||||
*/
|
||||
private static final int ANIMATION_START = 0;
|
||||
private static final int ANIMATION_FRAME = 1;
|
||||
|
||||
/**
|
||||
* Values used with internal variable mPlayingState to indicate the current state of an
|
||||
* animation.
|
||||
*/
|
||||
private static final int STOPPED = 0; // Not yet playing
|
||||
private static final int RUNNING = 1; // Playing normally
|
||||
private static final int CANCELED = 2; // cancel() called - need to end it
|
||||
private static final int ENDED = 3; // end() called - need to end it
|
||||
private static final int SEEKED = 4; // Seeked to some time value
|
||||
|
||||
/**
|
||||
* Internal variables
|
||||
* NOTE: This object implements the clone() method, making a deep copy of any referenced
|
||||
* objects. As other non-trivial fields are added to this class, make sure to add logic
|
||||
* to clone() to make deep copies of them.
|
||||
*/
|
||||
|
||||
// The first time that the animation's animateFrame() method is called. This time is used to
|
||||
// determine elapsed time (and therefore the elapsed fraction) in subsequent calls
|
||||
// to animateFrame()
|
||||
private long mStartTime;
|
||||
|
||||
/**
|
||||
* Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
|
||||
* to a value.
|
||||
*/
|
||||
private long mSeekTime = -1;
|
||||
|
||||
// The static sAnimationHandler processes the internal timing loop on which all animations
|
||||
// are based
|
||||
private static AnimationHandler sAnimationHandler;
|
||||
|
||||
// The static list of all active animations
|
||||
private static final ArrayList<ValueAnimator> sAnimations = new ArrayList<ValueAnimator>();
|
||||
|
||||
// The set of animations to be started on the next animation frame
|
||||
private static final ArrayList<ValueAnimator> sPendingAnimations = new ArrayList<ValueAnimator>();
|
||||
|
||||
// The time interpolator to be used if none is set on the animation
|
||||
private static final Interpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
|
||||
|
||||
// type evaluators for the three primitive types handled by this implementation
|
||||
private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
|
||||
private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
|
||||
private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator();
|
||||
|
||||
/**
|
||||
* Used to indicate whether the animation is currently playing in reverse. This causes the
|
||||
* elapsed fraction to be inverted to calculate the appropriate values.
|
||||
*/
|
||||
private boolean mPlayingBackwards = false;
|
||||
|
||||
/**
|
||||
* This variable tracks the current iteration that is playing. When mCurrentIteration exceeds the
|
||||
* repeatCount (if repeatCount!=INFINITE), the animation ends
|
||||
*/
|
||||
private int mCurrentIteration = 0;
|
||||
|
||||
/**
|
||||
* Tracks whether a startDelay'd animation has begun playing through the startDelay.
|
||||
*/
|
||||
private boolean mStartedDelay = false;
|
||||
|
||||
/**
|
||||
* Tracks the time at which the animation began playing through its startDelay. This is
|
||||
* different from the mStartTime variable, which is used to track when the animation became
|
||||
* active (which is when the startDelay expired and the animation was added to the active
|
||||
* animations list).
|
||||
*/
|
||||
private long mDelayStartTime;
|
||||
|
||||
/**
|
||||
* Flag that represents the current state of the animation. Used to figure out when to start
|
||||
* an animation (if state == STOPPED). Also used to end an animation that
|
||||
* has been cancel()'d or end()'d since the last animation frame. Possible values are
|
||||
* STOPPED, RUNNING, ENDED, CANCELED.
|
||||
*/
|
||||
private int mPlayingState = STOPPED;
|
||||
|
||||
/**
|
||||
* Internal collections used to avoid set collisions as animations start and end while being
|
||||
* processed.
|
||||
*/
|
||||
private static final ArrayList<ValueAnimator> sEndingAnims = new ArrayList<ValueAnimator>();
|
||||
private static final ArrayList<ValueAnimator> sDelayedAnims = new ArrayList<ValueAnimator>();
|
||||
private static final ArrayList<ValueAnimator> sReadyAnims = new ArrayList<ValueAnimator>();
|
||||
|
||||
/**
|
||||
* Flag that denotes whether the animation is set up and ready to go. Used to
|
||||
* set up animation that has not yet been started.
|
||||
*/
|
||||
boolean mInitialized = false;
|
||||
|
||||
//
|
||||
// Backing variables
|
||||
//
|
||||
|
||||
// How long the animation should last in ms
|
||||
private long mDuration;
|
||||
|
||||
// The amount of time in ms to delay starting the animation after start() is called
|
||||
private long mStartDelay = 0;
|
||||
|
||||
// The number of milliseconds between animation frames
|
||||
private static long sFrameDelay = DEFAULT_FRAME_DELAY;
|
||||
|
||||
// The number of times the animation will repeat. The default is 0, which means the animation
|
||||
// will play only once
|
||||
private int mRepeatCount = 0;
|
||||
|
||||
/**
|
||||
* The type of repetition that will occur when repeatMode is nonzero. RESTART means the
|
||||
* animation will start from the beginning on every new cycle. REVERSE means the animation
|
||||
* will reverse directions on each iteration.
|
||||
*/
|
||||
private int mRepeatMode = RESTART;
|
||||
|
||||
/**
|
||||
* The time interpolator to be used. The elapsed fraction of the animation will be passed
|
||||
* through this interpolator to calculate the interpolated fraction, which is then used to
|
||||
* calculate the animated values.
|
||||
*/
|
||||
private Interpolator mInterpolator = sDefaultInterpolator;
|
||||
|
||||
/**
|
||||
* The set of listeners to be sent events through the life of an animation.
|
||||
*/
|
||||
private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
|
||||
|
||||
/**
|
||||
* The property/value sets being animated.
|
||||
*/
|
||||
PropertyValuesHolder[] mValues;
|
||||
|
||||
/**
|
||||
* A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
|
||||
* by property name during calls to getAnimatedValue(String).
|
||||
*/
|
||||
HashMap<String, PropertyValuesHolder> mValuesMap;
|
||||
|
||||
/**
|
||||
* Public constants
|
||||
*/
|
||||
|
||||
/**
|
||||
* When the animation reaches the end and <code>repeatCount</code> is INFINITE
|
||||
* or a positive value, the animation restarts from the beginning.
|
||||
*/
|
||||
public static final int RESTART = 1;
|
||||
/**
|
||||
* When the animation reaches the end and <code>repeatCount</code> is INFINITE
|
||||
* or a positive value, the animation reverses direction on every iteration.
|
||||
*/
|
||||
public static final int REVERSE = 2;
|
||||
/**
|
||||
* This value used used with the {@link #setRepeatCount(int)} property to repeat
|
||||
* the animation indefinitely.
|
||||
*/
|
||||
public static final int INFINITE = -1;
|
||||
|
||||
/**
|
||||
* Creates a new ValueAnimator object. This default constructor is primarily for
|
||||
* use internally; the other constructors which take parameters are more generally
|
||||
* useful.
|
||||
*/
|
||||
public ValueAnimator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ValueAnimator object with the specified duration and set of
|
||||
* values. If the values are a set of PropertyValuesHolder objects, then these objects
|
||||
* define the potentially multiple properties being animated and the values the properties are
|
||||
* animated between. Otherwise, the values define a single set of values animated between.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param values The set of values to animate between. If these values are not
|
||||
* PropertyValuesHolder objects, then there should be more than one value, since the values
|
||||
* determine the interval to animate between.
|
||||
*/
|
||||
public ValueAnimator(long duration, T...values) {
|
||||
mDuration = duration;
|
||||
if (values.length > 0) {
|
||||
setValues(values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the values, per property, being animated between. This function is called internally
|
||||
* by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can
|
||||
* be constructed without values and this method can be called to set the values manually
|
||||
* instead.
|
||||
*
|
||||
* @param values The set of values, per property, being animated between.
|
||||
*/
|
||||
public void setValues(PropertyValuesHolder... values) {
|
||||
int numValues = values.length;
|
||||
mValues = values;
|
||||
mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
|
||||
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values that this ValueAnimator animates between. These values are stored in
|
||||
* PropertyValuesHolder objects, even if the ValueAnimator was created with a simple list
|
||||
* of value objects instead.
|
||||
*
|
||||
* @return PropertyValuesHolder[] An array of PropertyValuesHolder objects which hold the
|
||||
* values, per property, that define the animation.
|
||||
*/
|
||||
public PropertyValuesHolder[] getValues() {
|
||||
return mValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the values to animate between for this animation. If <code>values</code> is
|
||||
* a set of PropertyValuesHolder objects, these objects will become the set of properties
|
||||
* animated and the values that those properties are animated between. Otherwise, this method
|
||||
* will set only one set of values for the ValueAnimator. Also, if the values are not
|
||||
* PropertyValuesHolder objects and if there are already multiple sets of
|
||||
* values defined for this ValueAnimator via
|
||||
* more than one PropertyValuesHolder objects, this method will set the values for
|
||||
* the first of those objects.
|
||||
*
|
||||
* @param values The set of values to animate between.
|
||||
*/
|
||||
public void setValues(T... values) {
|
||||
if (mValues == null || mValues.length == 0) {
|
||||
setValues(new PropertyValuesHolder[]{
|
||||
new PropertyValuesHolder("", (Object[])values)});
|
||||
} else {
|
||||
PropertyValuesHolder valuesHolder = mValues[0];
|
||||
valuesHolder.setValues(values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called immediately before processing the first animation
|
||||
* frame of an animation. If there is a nonzero <code>startDelay</code>, the
|
||||
* function is called after that delay ends.
|
||||
* It takes care of the final initialization steps for the
|
||||
* animation.
|
||||
*
|
||||
* <p>Overrides of this method should call the superclass method to ensure
|
||||
* that internal mechanisms for the animation are set up correctly.</p>
|
||||
*/
|
||||
void initAnimation() {
|
||||
if (!mInitialized) {
|
||||
int numValues = mValues.length;
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
mValues[i].init();
|
||||
}
|
||||
mCurrentIteration = 0;
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the length of the animation.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
*/
|
||||
public void setDuration(long duration) {
|
||||
mDuration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of the animation.
|
||||
*
|
||||
* @return The length of the animation, in milliseconds.
|
||||
*/
|
||||
public long getDuration() {
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the animation to the specified point in time. This time should
|
||||
* 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 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.
|
||||
*/
|
||||
public void setCurrentPlayTime(long playTime) {
|
||||
initAnimation();
|
||||
long currentTime = AnimationUtils.currentAnimationTimeMillis();
|
||||
if (mPlayingState != RUNNING) {
|
||||
mSeekTime = playTime;
|
||||
mPlayingState = SEEKED;
|
||||
}
|
||||
mStartTime = currentTime - playTime;
|
||||
animationFrame(currentTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current position of the animation in time, which is equal to the current
|
||||
* time minus the time that the animation started. An animation that is not yet started will
|
||||
* return a value of zero.
|
||||
*
|
||||
* @return The current position in time of the animation.
|
||||
*/
|
||||
public long getCurrentPlayTime() {
|
||||
if (!mInitialized || mPlayingState == STOPPED) {
|
||||
return 0;
|
||||
}
|
||||
return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* This custom, static handler handles the timing pulse that is shared by
|
||||
* all active animations. This approach ensures that the setting of animation
|
||||
* values will happen on the UI thread and that all animations will share
|
||||
* the same times for calculating their values, which makes synchronizing
|
||||
* animations possible.
|
||||
*
|
||||
*/
|
||||
private static class AnimationHandler extends Handler {
|
||||
/**
|
||||
* There are only two messages that we care about: ANIMATION_START and
|
||||
* ANIMATION_FRAME. The START message is sent when an animation's start()
|
||||
* method is called. It cannot start synchronously when start() is called
|
||||
* because the call may be on the wrong thread, and it would also not be
|
||||
* synchronized with other animations because it would not start on a common
|
||||
* timing pulse. So each animation sends a START message to the handler, which
|
||||
* causes the handler to place the animation on the active animations queue and
|
||||
* start processing frames for that animation.
|
||||
* The FRAME message is the one that is sent over and over while there are any
|
||||
* active animations to process.
|
||||
*/
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
boolean callAgain = true;
|
||||
switch (msg.what) {
|
||||
// TODO: should we avoid sending frame message when starting if we
|
||||
// were already running?
|
||||
case ANIMATION_START:
|
||||
if (sAnimations.size() > 0 || sDelayedAnims.size() > 0) {
|
||||
callAgain = false;
|
||||
}
|
||||
// pendingAnims holds any animations that have requested to be started
|
||||
// We're going to clear sPendingAnimations, but starting animation may
|
||||
// cause more to be added to the pending list (for example, if one animation
|
||||
// starting triggers another starting). So we loop until sPendingAnimations
|
||||
// is empty.
|
||||
while (sPendingAnimations.size() > 0) {
|
||||
ArrayList<ValueAnimator> pendingCopy =
|
||||
(ArrayList<ValueAnimator>) sPendingAnimations.clone();
|
||||
sPendingAnimations.clear();
|
||||
int count = pendingCopy.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ValueAnimator anim = pendingCopy.get(i);
|
||||
// If the animation has a startDelay, place it on the delayed list
|
||||
if (anim.mStartDelay == 0 || anim.mPlayingState == ENDED ||
|
||||
anim.mPlayingState == CANCELED) {
|
||||
anim.startAnimation();
|
||||
} else {
|
||||
sDelayedAnims.add(anim);
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through to process first frame of new animations
|
||||
case ANIMATION_FRAME:
|
||||
// currentTime holds the common time for all animations processed
|
||||
// during this frame
|
||||
long currentTime = AnimationUtils.currentAnimationTimeMillis();
|
||||
|
||||
// First, process animations currently sitting on the delayed queue, adding
|
||||
// them to the active animations if they are ready
|
||||
int numDelayedAnims = sDelayedAnims.size();
|
||||
for (int i = 0; i < numDelayedAnims; ++i) {
|
||||
ValueAnimator anim = sDelayedAnims.get(i);
|
||||
if (anim.delayedAnimationFrame(currentTime)) {
|
||||
sReadyAnims.add(anim);
|
||||
}
|
||||
}
|
||||
int numReadyAnims = sReadyAnims.size();
|
||||
if (numReadyAnims > 0) {
|
||||
for (int i = 0; i < numReadyAnims; ++i) {
|
||||
ValueAnimator anim = sReadyAnims.get(i);
|
||||
anim.startAnimation();
|
||||
sDelayedAnims.remove(anim);
|
||||
}
|
||||
sReadyAnims.clear();
|
||||
}
|
||||
|
||||
// Now process all active animations. The return value from animationFrame()
|
||||
// tells the handler whether it should now be ended
|
||||
int numAnims = sAnimations.size();
|
||||
for (int i = 0; i < numAnims; ++i) {
|
||||
ValueAnimator anim = sAnimations.get(i);
|
||||
if (anim.animationFrame(currentTime)) {
|
||||
sEndingAnims.add(anim);
|
||||
}
|
||||
}
|
||||
if (sEndingAnims.size() > 0) {
|
||||
for (int i = 0; i < sEndingAnims.size(); ++i) {
|
||||
sEndingAnims.get(i).endAnimation();
|
||||
}
|
||||
sEndingAnims.clear();
|
||||
}
|
||||
|
||||
// If there are still active or delayed animations, call the handler again
|
||||
// after the frameDelay
|
||||
if (callAgain && (!sAnimations.isEmpty() || !sDelayedAnims.isEmpty())) {
|
||||
sendEmptyMessageDelayed(ANIMATION_FRAME, sFrameDelay);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, to delay starting the animation after
|
||||
* {@link #start()} is called.
|
||||
*
|
||||
* @return the number of milliseconds to delay running the animation
|
||||
*/
|
||||
public long getStartDelay() {
|
||||
return mStartDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, to delay starting the animation after
|
||||
* {@link #start()} is called.
|
||||
|
||||
* @param startDelay The amount of the delay, in milliseconds
|
||||
*/
|
||||
public void setStartDelay(long startDelay) {
|
||||
this.mStartDelay = startDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, between each frame of the animation. This is a
|
||||
* requested time that the animation will attempt to honor, but the actual delay between
|
||||
* frames may be different, depending on system load and capabilities. This is a static
|
||||
* function because the same delay will be applied to all animations, since they are all
|
||||
* run off of a single timing loop.
|
||||
*
|
||||
* @return the requested time between frames, in milliseconds
|
||||
*/
|
||||
public static long getFrameDelay() {
|
||||
return sFrameDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, between each frame of the animation. This is a
|
||||
* requested time that the animation will attempt to honor, but the actual delay between
|
||||
* frames may be different, depending on system load and capabilities. This is a static
|
||||
* function because the same delay will be applied to all animations, since they are all
|
||||
* run off of a single timing loop.
|
||||
*
|
||||
* @param frameDelay the requested time between frames, in milliseconds
|
||||
*/
|
||||
public static void setFrameDelay(long frameDelay) {
|
||||
sFrameDelay = frameDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* The most recent value calculated by this <code>ValueAnimator</code> when there is just one
|
||||
* property being animated. This value is only sensible while the animation is running. The main
|
||||
* purpose for this read-only property is to retrieve the value from the <code>ValueAnimator</code>
|
||||
* during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
|
||||
* is called during each animation frame, immediately after the value is calculated.
|
||||
*
|
||||
* @return animatedValue The value most recently calculated by this <code>ValueAnimator</code> for
|
||||
* the single property being animated. If there are several properties being animated
|
||||
* (specified by several PropertyValuesHolder objects in the constructor), this function
|
||||
* returns the animated value for the first of those objects.
|
||||
*/
|
||||
public Object getAnimatedValue() {
|
||||
if (mValues != null && mValues.length > 0) {
|
||||
return mValues[0].getAnimatedValue();
|
||||
}
|
||||
// Shouldn't get here; should always have values unless ValueAnimator was set up wrong
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The most recent value calculated by this <code>ValueAnimator</code> for <code>propertyName</code>.
|
||||
* The main purpose for this read-only property is to retrieve the value from the
|
||||
* <code>ValueAnimator</code> during a call to
|
||||
* {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which
|
||||
* is called during each animation frame, immediately after the value is calculated.
|
||||
*
|
||||
* @return animatedValue The value most recently calculated for the named property
|
||||
* by this <code>ValueAnimator</code>.
|
||||
*/
|
||||
public Object getAnimatedValue(String propertyName) {
|
||||
PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
|
||||
if (valuesHolder != null) {
|
||||
return valuesHolder.getAnimatedValue();
|
||||
} else {
|
||||
// At least avoid crashing if called with bogus propertyName
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how many times the animation should be repeated. If the repeat
|
||||
* count is 0, the animation is never repeated. If the repeat count is
|
||||
* greater than 0 or {@link #INFINITE}, the repeat mode will be taken
|
||||
* into account. The repeat count is 0 by default.
|
||||
*
|
||||
* @param value the number of times the animation should be repeated
|
||||
*/
|
||||
public void setRepeatCount(int value) {
|
||||
mRepeatCount = value;
|
||||
}
|
||||
/**
|
||||
* Defines how many times the animation should repeat. The default value
|
||||
* is 0.
|
||||
*
|
||||
* @return the number of times the animation should repeat, or {@link #INFINITE}
|
||||
*/
|
||||
public int getRepeatCount() {
|
||||
return mRepeatCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines what this animation should do when it reaches the end. This
|
||||
* setting is applied only when the repeat count is either greater than
|
||||
* 0 or {@link #INFINITE}. Defaults to {@link #RESTART}.
|
||||
*
|
||||
* @param value {@link #RESTART} or {@link #REVERSE}
|
||||
*/
|
||||
public void setRepeatMode(int value) {
|
||||
mRepeatMode = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines what this animation should do when it reaches the end.
|
||||
*
|
||||
* @return either one of {@link #REVERSE} or {@link #RESTART}
|
||||
*/
|
||||
public int getRepeatMode() {
|
||||
return mRepeatMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to the set of listeners that are sent update events through the life of
|
||||
* an animation. This method is called on all listeners for every frame of the animation,
|
||||
* after the values for the animation have been calculated.
|
||||
*
|
||||
* @param listener the listener to be added to the current set of listeners for this animation.
|
||||
*/
|
||||
public void addUpdateListener(AnimatorUpdateListener listener) {
|
||||
if (mUpdateListeners == null) {
|
||||
mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
|
||||
}
|
||||
mUpdateListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from the set listening to frame updates for this animation.
|
||||
*
|
||||
* @param listener the listener to be removed from the current set of update listeners
|
||||
* for this animation.
|
||||
*/
|
||||
public void removeUpdateListener(AnimatorUpdateListener listener) {
|
||||
if (mUpdateListeners == null) {
|
||||
return;
|
||||
}
|
||||
mUpdateListeners.remove(listener);
|
||||
if (mUpdateListeners.size() == 0) {
|
||||
mUpdateListeners = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The time interpolator used in calculating the elapsed fraction of this animation. The
|
||||
* interpolator determines whether the animation runs with linear or non-linear motion,
|
||||
* such as acceleration and deceleration. The default value is
|
||||
* {@link android.view.animation.AccelerateDecelerateInterpolator}
|
||||
*
|
||||
* @param value the interpolator to be used by this animation
|
||||
*/
|
||||
@Override
|
||||
public void setInterpolator(Interpolator value) {
|
||||
if (value != null) {
|
||||
mInterpolator = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timing interpolator that this ValueAnimator uses.
|
||||
*
|
||||
* @return The timing interpolator for this ValueAnimator.
|
||||
*/
|
||||
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
|
||||
* of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values
|
||||
* are not one of these primitive types, or if different evaluation is desired (such as is
|
||||
* necessary with int values that represent colors), a custom evaluator needs to be assigned.
|
||||
* For example, when running an animation on color values, the {@link RGBEvaluator}
|
||||
* should be used to get correct RGB color interpolation.
|
||||
*
|
||||
* <p>If this ValueAnimator has only one set of values being animated between, this evaluator
|
||||
* will be used for that set. If there are several sets of values being animated, which is
|
||||
* the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator
|
||||
* is assigned just to the first PropertyValuesHolder object.</p>
|
||||
*
|
||||
* @param value the evaluator to be used this animation
|
||||
*/
|
||||
public void setEvaluator(TypeEvaluator value) {
|
||||
if (value != null && mValues != null && mValues.length > 0) {
|
||||
mValues[0].setEvaluator(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the animation playing. This version of start() takes a boolean flag that indicates
|
||||
* whether the animation should play in reverse. The flag is usually false, but may be set
|
||||
* to true if called from the reverse() method/
|
||||
*
|
||||
* @param playBackwards Whether the ValueAnimator should start playing in reverse.
|
||||
*/
|
||||
private void start(boolean playBackwards) {
|
||||
mPlayingBackwards = 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());
|
||||
}
|
||||
mPlayingState = STOPPED;
|
||||
mStartedDelay = false;
|
||||
sPendingAnimations.add(this);
|
||||
if (sAnimationHandler == null) {
|
||||
sAnimationHandler = new AnimationHandler();
|
||||
}
|
||||
// TODO: does this put too many messages on the queue if the handler
|
||||
// is already running?
|
||||
sAnimationHandler.sendEmptyMessage(ANIMATION_START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
start(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationCancel(this);
|
||||
}
|
||||
}
|
||||
// Just set the CANCELED flag - this causes the animation to end the next time a frame
|
||||
// is processed.
|
||||
mPlayingState = CANCELED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if (!sAnimations.contains(this) && !sPendingAnimations.contains(this)) {
|
||||
// Special case if the animation has not yet started; get it ready for ending
|
||||
mStartedDelay = false;
|
||||
sPendingAnimations.add(this);
|
||||
if (sAnimationHandler == null) {
|
||||
sAnimationHandler = new AnimationHandler();
|
||||
}
|
||||
sAnimationHandler.sendEmptyMessage(ANIMATION_START);
|
||||
}
|
||||
// Just set the ENDED flag - this causes the animation to end the next time a frame
|
||||
// is processed.
|
||||
mPlayingState = ENDED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
// ENDED or CANCELED indicate that it has been ended or canceled, but not processed yet
|
||||
return (mPlayingState == RUNNING || mPlayingState == ENDED || mPlayingState == CANCELED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the ValueAnimator in reverse. If the animation is already running,
|
||||
* it will stop itself and play backwards from the point reached when reverse was called.
|
||||
* If the animation is not currently running, then it will start from the end and
|
||||
* play backwards. This behavior is only set for the current animation; future playing
|
||||
* of the animation will use the default behavior of playing forward.
|
||||
*/
|
||||
public void reverse() {
|
||||
mPlayingBackwards = !mPlayingBackwards;
|
||||
if (mPlayingState == RUNNING) {
|
||||
long currentTime = AnimationUtils.currentAnimationTimeMillis();
|
||||
long currentPlayTime = currentTime - mStartTime;
|
||||
long timeLeft = mDuration - currentPlayTime;
|
||||
mStartTime = currentTime - timeLeft;
|
||||
} else {
|
||||
start(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally to end an animation by removing it from the animations list. Must be
|
||||
* called on the UI thread.
|
||||
*/
|
||||
private void endAnimation() {
|
||||
sAnimations.remove(this);
|
||||
mPlayingState = STOPPED;
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationEnd(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally to start an animation by adding it to the active animations list. Must be
|
||||
* called on the UI thread.
|
||||
*/
|
||||
private void startAnimation() {
|
||||
initAnimation();
|
||||
sAnimations.add(this);
|
||||
if (mListeners != null) {
|
||||
ArrayList<AnimatorListener> tmpListeners =
|
||||
(ArrayList<AnimatorListener>) mListeners.clone();
|
||||
for (AnimatorListener listener : tmpListeners) {
|
||||
listener.onAnimationStart(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function called to process an animation frame on an animation that is currently
|
||||
* sleeping through its <code>startDelay</code> phase. The return value indicates whether it
|
||||
* should be woken up and put on the active animations queue.
|
||||
*
|
||||
* @param currentTime The current animation time, used to calculate whether the animation
|
||||
* has exceeded its <code>startDelay</code> and should be started.
|
||||
* @return True if the animation's <code>startDelay</code> has been exceeded and the animation
|
||||
* should be added to the set of active animations.
|
||||
*/
|
||||
private boolean delayedAnimationFrame(long currentTime) {
|
||||
if (mPlayingState == CANCELED || mPlayingState == ENDED) {
|
||||
// end the delay, process an animation frame to actually cancel it
|
||||
return true;
|
||||
}
|
||||
if (!mStartedDelay) {
|
||||
mStartedDelay = true;
|
||||
mDelayStartTime = currentTime;
|
||||
} else {
|
||||
long deltaTime = currentTime - mDelayStartTime;
|
||||
if (deltaTime > mStartDelay) {
|
||||
// startDelay ended - start the anim and record the
|
||||
// mStartTime appropriately
|
||||
mStartTime = currentTime - (deltaTime - mStartDelay);
|
||||
mPlayingState = RUNNING;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This internal function processes a single animation frame for a given animation. The
|
||||
* currentTime parameter is the timing pulse sent by the handler, used to calculate the
|
||||
* elapsed duration, and therefore
|
||||
* the elapsed fraction, of the animation. The return value indicates whether the animation
|
||||
* should be ended (which happens when the elapsed time of the animation exceeds the
|
||||
* animation's duration, including the repeatCount).
|
||||
*
|
||||
* @param currentTime The current time, as tracked by the static timing handler
|
||||
* @return true if the animation's duration, including any repetitions due to
|
||||
* <code>repeatCount</code> has been exceeded and the animation should be ended.
|
||||
*/
|
||||
private boolean animationFrame(long currentTime) {
|
||||
boolean done = false;
|
||||
|
||||
if (mPlayingState == STOPPED) {
|
||||
mPlayingState = RUNNING;
|
||||
if (mSeekTime < 0) {
|
||||
mStartTime = currentTime;
|
||||
} else {
|
||||
mStartTime = currentTime - mSeekTime;
|
||||
// Now that we're playing, reset the seek time
|
||||
mSeekTime = -1;
|
||||
}
|
||||
}
|
||||
switch (mPlayingState) {
|
||||
case RUNNING:
|
||||
case SEEKED:
|
||||
float fraction = (float)(currentTime - mStartTime) / mDuration;
|
||||
if (fraction >= 1f) {
|
||||
if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
|
||||
// Time to repeat
|
||||
if (mListeners != null) {
|
||||
for (AnimatorListener listener : mListeners) {
|
||||
listener.onAnimationRepeat(this);
|
||||
}
|
||||
}
|
||||
++mCurrentIteration;
|
||||
if (mRepeatMode == REVERSE) {
|
||||
mPlayingBackwards = mPlayingBackwards ? false : true;
|
||||
}
|
||||
// TODO: doesn't account for fraction going Wayyyyy over 1, like 2+
|
||||
fraction = fraction - 1f;
|
||||
mStartTime += mDuration;
|
||||
} else {
|
||||
done = true;
|
||||
fraction = Math.min(fraction, 1.0f);
|
||||
}
|
||||
}
|
||||
if (mPlayingBackwards) {
|
||||
fraction = 1f - fraction;
|
||||
}
|
||||
animateValue(fraction);
|
||||
break;
|
||||
case ENDED:
|
||||
// The final value set on the target varies, depending on whether the animation
|
||||
// was supposed to repeat an odd number of times
|
||||
if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
|
||||
animateValue(0f);
|
||||
} else {
|
||||
animateValue(1f);
|
||||
}
|
||||
// Fall through to set done flag
|
||||
case CANCELED:
|
||||
done = true;
|
||||
mPlayingState = STOPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called with the elapsed fraction of the animation during every
|
||||
* animation frame. This function turns the elapsed fraction into an interpolated fraction
|
||||
* and then into an animated value (from the evaluator. The function is called mostly during
|
||||
* animation updates, but it is also called when the <code>end()</code>
|
||||
* function is called, to set the final value on the property.
|
||||
*
|
||||
* <p>Overrides of this method must call the superclass to perform the calculation
|
||||
* of the animated value.</p>
|
||||
*
|
||||
* @param fraction The elapsed fraction of the animation.
|
||||
*/
|
||||
void animateValue(float fraction) {
|
||||
fraction = mInterpolator.getInterpolation(fraction);
|
||||
int numValues = mValues.length;
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
mValues[i].calculateValue(fraction);
|
||||
}
|
||||
if (mUpdateListeners != null) {
|
||||
int numListeners = mUpdateListeners.size();
|
||||
for (int i = 0; i < numListeners; ++i) {
|
||||
mUpdateListeners.get(i).onAnimationUpdate(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueAnimator clone() {
|
||||
final ValueAnimator anim = (ValueAnimator) super.clone();
|
||||
if (mUpdateListeners != null) {
|
||||
ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
|
||||
anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
|
||||
int numListeners = oldListeners.size();
|
||||
for (int i = 0; i < numListeners; ++i) {
|
||||
anim.mUpdateListeners.add(oldListeners.get(i));
|
||||
}
|
||||
}
|
||||
anim.mSeekTime = -1;
|
||||
anim.mPlayingBackwards = false;
|
||||
anim.mCurrentIteration = 0;
|
||||
anim.mInitialized = false;
|
||||
anim.mPlayingState = STOPPED;
|
||||
anim.mStartedDelay = false;
|
||||
PropertyValuesHolder[] oldValues = mValues;
|
||||
if (oldValues != null) {
|
||||
int numValues = oldValues.length;
|
||||
anim.mValues = new PropertyValuesHolder[numValues];
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
anim.mValues[i] = oldValues[i].clone();
|
||||
}
|
||||
anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
PropertyValuesHolder valuesHolder = mValues[i];
|
||||
anim.mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
|
||||
}
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementors of this interface can add themselves as update listeners
|
||||
* to an <code>ValueAnimator</code> instance to receive callbacks on every animation
|
||||
* frame, after the current frame's values have been calculated for that
|
||||
* <code>ValueAnimator</code>.
|
||||
*/
|
||||
public static interface AnimatorUpdateListener {
|
||||
/**
|
||||
* <p>Notifies the occurrence of another frame of the animation.</p>
|
||||
*
|
||||
* @param animation The animation which was repeated.
|
||||
*/
|
||||
void onAnimationUpdate(ValueAnimator animation);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.animation.Animatable;
|
||||
import android.animation.Animator;
|
||||
import android.content.ComponentCallbacks;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -26,7 +26,6 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -755,7 +754,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
|
||||
/**
|
||||
* Called when a fragment loads an animation.
|
||||
*/
|
||||
public Animatable onCreateAnimatable(int transit, boolean enter, int nextAnim) {
|
||||
public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.animation.Animatable;
|
||||
import android.animation.AnimatableInflater;
|
||||
import android.animation.PropertyAnimator;
|
||||
import android.animation.Sequencer;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -248,16 +248,16 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
return f;
|
||||
}
|
||||
|
||||
Animatable loadAnimatable(Fragment fragment, int transit, boolean enter,
|
||||
Animator loadAnimator(Fragment fragment, int transit, boolean enter,
|
||||
int transitionStyle) {
|
||||
Animatable animObj = fragment.onCreateAnimatable(transit, enter,
|
||||
Animator animObj = fragment.onCreateAnimator(transit, enter,
|
||||
fragment.mNextAnim);
|
||||
if (animObj != null) {
|
||||
return animObj;
|
||||
}
|
||||
|
||||
if (fragment.mNextAnim != 0) {
|
||||
Animatable anim = AnimatableInflater.loadAnimatable(mActivity, fragment.mNextAnim);
|
||||
Animator anim = AnimatorInflater.loadAnimator(mActivity, fragment.mNextAnim);
|
||||
if (anim != null) {
|
||||
return anim;
|
||||
}
|
||||
@@ -288,7 +288,7 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
return AnimatableInflater.loadAnimatable(mActivity, anim);
|
||||
return AnimatorInflater.loadAnimator(mActivity, anim);
|
||||
}
|
||||
|
||||
void moveToState(Fragment f, int newState, int transit, int transitionStyle) {
|
||||
@@ -360,13 +360,13 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
if (f.mView != null) {
|
||||
f.mView.setSaveFromParentEnabled(false);
|
||||
if (container != null) {
|
||||
Animatable anim = loadAnimatable(f, transit, true,
|
||||
Animator anim = loadAnimator(f, transit, true,
|
||||
transitionStyle);
|
||||
if (anim != null) {
|
||||
if (anim instanceof Sequencer) {
|
||||
((Sequencer)anim).setTarget(f.mView);
|
||||
} else if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator)anim).setTarget(f.mView);
|
||||
if (anim instanceof AnimatorSet) {
|
||||
((AnimatorSet)anim).setTarget(f.mView);
|
||||
} else if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator)anim).setTarget(f.mView);
|
||||
}
|
||||
anim.start();
|
||||
}
|
||||
@@ -448,13 +448,13 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
}
|
||||
if (f.mView != null && f.mContainer != null) {
|
||||
if (mCurState > Fragment.INITIALIZING) {
|
||||
Animatable anim = loadAnimatable(f, transit, true,
|
||||
Animator anim = loadAnimator(f, transit, true,
|
||||
transitionStyle);
|
||||
if (anim != null) {
|
||||
if (anim instanceof Sequencer) {
|
||||
((Sequencer)anim).setTarget(f.mView);
|
||||
} else if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator)anim).setTarget(f.mView);
|
||||
if (anim instanceof AnimatorSet) {
|
||||
((AnimatorSet)anim).setTarget(f.mView);
|
||||
} else if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator)anim).setTarget(f.mView);
|
||||
}
|
||||
anim.start();
|
||||
}
|
||||
@@ -588,13 +588,13 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
if (!fragment.mHidden) {
|
||||
fragment.mHidden = true;
|
||||
if (fragment.mView != null) {
|
||||
Animatable anim = loadAnimatable(fragment, transition, true,
|
||||
Animator anim = loadAnimator(fragment, transition, true,
|
||||
transitionStyle);
|
||||
if (anim != null) {
|
||||
if (anim instanceof Sequencer) {
|
||||
((Sequencer)anim).setTarget(fragment.mView);
|
||||
} else if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator)anim).setTarget(fragment.mView);
|
||||
if (anim instanceof AnimatorSet) {
|
||||
((AnimatorSet)anim).setTarget(fragment.mView);
|
||||
} else if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator)anim).setTarget(fragment.mView);
|
||||
}
|
||||
anim.start();
|
||||
}
|
||||
@@ -612,13 +612,13 @@ final class FragmentManagerImpl implements FragmentManager {
|
||||
if (fragment.mHidden) {
|
||||
fragment.mHidden = false;
|
||||
if (fragment.mView != null) {
|
||||
Animatable anim = loadAnimatable(fragment, transition, true,
|
||||
Animator anim = loadAnimator(fragment, transition, true,
|
||||
transitionStyle);
|
||||
if (anim != null) {
|
||||
if (anim instanceof Sequencer) {
|
||||
((Sequencer)anim).setTarget(fragment.mView);
|
||||
} else if (anim instanceof PropertyAnimator) {
|
||||
((PropertyAnimator)anim).setTarget(fragment.mView);
|
||||
if (anim instanceof AnimatorSet) {
|
||||
((AnimatorSet)anim).setTarget(fragment.mView);
|
||||
} else if (anim instanceof ObjectAnimator) {
|
||||
((ObjectAnimator)anim).setTarget(fragment.mView);
|
||||
}
|
||||
anim.start();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import java.io.IOException;
|
||||
public class AnimationUtils {
|
||||
|
||||
/**
|
||||
* These flags are used when parsing Sequencer objects
|
||||
* These flags are used when parsing AnimatorSet objects
|
||||
*/
|
||||
private static final int TOGETHER = 0;
|
||||
private static final int SEQUENTIALLY = 1;
|
||||
|
||||
@@ -18,12 +18,10 @@ package android.widget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.animation.PropertyAnimator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
@@ -220,13 +218,13 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
|
||||
* @param view The view that is being animated
|
||||
*/
|
||||
void animateViewForTransition(int fromIndex, int toIndex, View view) {
|
||||
PropertyAnimator pa;
|
||||
ObjectAnimator pa;
|
||||
if (fromIndex == -1) {
|
||||
view.setAlpha(0.0f);
|
||||
pa = new PropertyAnimator(400, view, "alpha", 0.0f, 1.0f);
|
||||
pa = new ObjectAnimator(400, view, "alpha", 0.0f, 1.0f);
|
||||
pa.start();
|
||||
} else if (toIndex == -1) {
|
||||
pa = new PropertyAnimator(400, view, "alpha", 1.0f, 0.0f);
|
||||
pa = new ObjectAnimator(400, view, "alpha", 1.0f, 0.0f);
|
||||
pa.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package android.widget;
|
||||
|
||||
import android.animation.PropertyAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BlurMaskFilter;
|
||||
@@ -166,7 +166,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
}
|
||||
view.setVisibility(VISIBLE);
|
||||
|
||||
PropertyAnimator<Float> fadeIn = new PropertyAnimator<Float>(DEFAULT_ANIMATION_DURATION,
|
||||
ObjectAnimator<Float> fadeIn = new ObjectAnimator<Float>(DEFAULT_ANIMATION_DURATION,
|
||||
view, "alpha", view.getAlpha(), 1.0f);
|
||||
fadeIn.start();
|
||||
} else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) {
|
||||
@@ -181,7 +181,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
new PropertyValuesHolder<Float>("YProgress", 0.0f);
|
||||
PropertyValuesHolder<Float> slideInX =
|
||||
new PropertyValuesHolder<Float>("XProgress", 0.0f);
|
||||
PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
|
||||
ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
|
||||
slideInX, slideInY);
|
||||
pa.setInterpolator(new LinearInterpolator());
|
||||
pa.start();
|
||||
@@ -196,7 +196,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
new PropertyValuesHolder<Float>("YProgress", 1.0f);
|
||||
PropertyValuesHolder<Float> slideOutX =
|
||||
new PropertyValuesHolder<Float>("XProgress", 0.0f);
|
||||
PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
|
||||
ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
|
||||
slideOutX, slideOutY);
|
||||
pa.setInterpolator(new LinearInterpolator());
|
||||
pa.start();
|
||||
@@ -208,7 +208,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
lp.setVerticalOffset(-mViewHeight);
|
||||
} else if (toIndex == -1) {
|
||||
// Fade item out
|
||||
PropertyAnimator<Float> fadeOut = new PropertyAnimator<Float>
|
||||
ObjectAnimator<Float> fadeOut = new ObjectAnimator<Float>
|
||||
(DEFAULT_ANIMATION_DURATION, view, "alpha", view.getAlpha(), 0.0f);
|
||||
fadeOut.start();
|
||||
}
|
||||
@@ -234,7 +234,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
|
||||
PropertyValuesHolder<Float> translationY =
|
||||
new PropertyValuesHolder<Float>("translationY", transY);
|
||||
PropertyAnimator pa = new PropertyAnimator(100, view, scaleX, scaleY, translationY);
|
||||
ObjectAnimator pa = new ObjectAnimator(100, view, scaleX, scaleY, translationY);
|
||||
pa.start();
|
||||
}
|
||||
}
|
||||
@@ -510,7 +510,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
new PropertyValuesHolder<Float>("YProgress", finalYProgress);
|
||||
PropertyValuesHolder<Float> snapBackX =
|
||||
new PropertyValuesHolder<Float>("XProgress", 0.0f);
|
||||
PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
|
||||
ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
|
||||
snapBackX, snapBackY);
|
||||
pa.setInterpolator(new LinearInterpolator());
|
||||
pa.start();
|
||||
@@ -529,7 +529,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
new PropertyValuesHolder<Float>("YProgress", finalYProgress);
|
||||
PropertyValuesHolder<Float> snapBackX =
|
||||
new PropertyValuesHolder<Float>("XProgress", 0.0f);
|
||||
PropertyAnimator pa = new PropertyAnimator(duration, animationSlider,
|
||||
ObjectAnimator pa = new ObjectAnimator(duration, animationSlider,
|
||||
snapBackX, snapBackY);
|
||||
pa.start();
|
||||
}
|
||||
@@ -870,7 +870,7 @@ public class StackView extends AdapterViewAnimator {
|
||||
|
||||
private Rect invalidateRect = new Rect();
|
||||
private RectF invalidateRectf = new RectF();
|
||||
// This is public so that PropertyAnimator can access it
|
||||
// This is public so that ObjectAnimator can access it
|
||||
public void setVerticalOffset(int newVerticalOffset) {
|
||||
int offsetDelta = newVerticalOffset - verticalOffset;
|
||||
verticalOffset = newVerticalOffset;
|
||||
|
||||
@@ -416,7 +416,7 @@ public class SlidingTab extends ViewGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start animating the slider. Note we need two animations since an Animator
|
||||
* Start animating the slider. Note we need two animations since an ValueAnimator
|
||||
* keeps internal state of the invalidation region which is just the view being animated.
|
||||
*
|
||||
* @param anim1
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
-->
|
||||
|
||||
<property xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
-->
|
||||
|
||||
<property xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0"
|
||||
|
||||
@@ -16,33 +16,33 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<property
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleY"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="alpha"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="-400"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="translationX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
</sequencer>
|
||||
</set>
|
||||
@@ -16,33 +16,33 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<property
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1"
|
||||
android:valueTo=".5"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1"
|
||||
android:valueTo=".5"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleY"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="alpha"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="400"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="translationX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
</sequencer>
|
||||
</set>
|
||||
@@ -16,31 +16,31 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<property
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/decelerate_interpolator"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleY"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="alpha"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:valueFrom="400"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="translationX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
</sequencer>
|
||||
</set>
|
||||
@@ -16,31 +16,31 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<sequencer xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<property
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="2"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:interpolator="@anim/accelerate_interpolator"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="2"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="scaleY"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:valueFrom="1"
|
||||
android:valueTo="0"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="alpha"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<property
|
||||
<objectAnimator
|
||||
android:valueFrom="0"
|
||||
android:valueTo="-400"
|
||||
android:valueType="floatType"
|
||||
android:propertyName="translationX"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
</sequencer>
|
||||
</set>
|
||||
@@ -3010,7 +3010,7 @@
|
||||
</declare-styleable>
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- Animator class attributes -->
|
||||
<!-- ValueAnimator class attributes -->
|
||||
<!-- ========================== -->
|
||||
<eat-comment />
|
||||
|
||||
@@ -3047,7 +3047,7 @@
|
||||
</declare-styleable>
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- PropertyAnimator class attributes -->
|
||||
<!-- ObjectAnimator class attributes -->
|
||||
<!-- ========================== -->
|
||||
<eat-comment />
|
||||
|
||||
@@ -3058,11 +3058,11 @@
|
||||
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- Sequencer class attributes -->
|
||||
<!-- AnimatorSet class attributes -->
|
||||
<!-- ========================== -->
|
||||
<eat-comment />
|
||||
|
||||
<declare-styleable name="Sequencer">
|
||||
<declare-styleable name="AnimatorSet">
|
||||
<!-- Name of the property being animated. -->
|
||||
<attr name="ordering">
|
||||
<!-- child animations should be played together. -->
|
||||
|
||||
@@ -16,13 +16,9 @@
|
||||
|
||||
package com.android.systemui.statusbar.tablet;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.app.StatusBarManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -33,7 +29,6 @@ import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -41,7 +36,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerImpl;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RemoteViews;
|
||||
@@ -50,7 +44,6 @@ import android.widget.TextSwitcher;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
import com.android.internal.statusbar.StatusBarIconList;
|
||||
import com.android.internal.statusbar.StatusBarNotification;
|
||||
|
||||
import com.android.systemui.statusbar.*;
|
||||
|
||||
Reference in New Issue
Block a user