Fields Summary |
---|
final View | mViewThe View whose properties are being animated by this class. This is set at
construction time. |
private long | mDurationThe duration of the underlying Animator object. By default, we don't set the duration
on the Animator and just use its default duration. If the duration is ever set on this
Animator, then we use the duration that it was set to. |
private boolean | mDurationSetA flag indicating whether the duration has been set on this object. If not, we don't set
the duration on the underlying Animator, but instead just use its default duration. |
private long | mStartDelayThe startDelay of the underlying Animator object. By default, we don't set the startDelay
on the Animator and just use its default startDelay. If the startDelay is ever set on this
Animator, then we use the startDelay that it was set to. |
private boolean | mStartDelaySetA flag indicating whether the startDelay has been set on this object. If not, we don't set
the startDelay on the underlying Animator, but instead just use its default startDelay. |
private android.animation.TimeInterpolator | mInterpolatorThe interpolator of the underlying Animator object. By default, we don't set the interpolator
on the Animator and just use its default interpolator. If the interpolator is ever set on
this Animator, then we use the interpolator that it was set to. |
private boolean | mInterpolatorSetA flag indicating whether the interpolator has been set on this object. If not, we don't set
the interpolator on the underlying Animator, but instead just use its default interpolator. |
private Animator.AnimatorListener | mListenerListener for the lifecycle events of the underlying ValueAnimator object. |
private ValueAnimator.AnimatorUpdateListener | mUpdateListenerListener for the update events of the underlying ValueAnimator object. |
private android.animation.ValueAnimator | mTempValueAnimatorA lazily-created ValueAnimator used in order to get some default animator properties
(duration, start delay, interpolator, etc.). |
private ViewPropertyAnimatorRT | mRTBackendA RenderThread-driven backend that may intercept startAnimation |
private AnimatorEventListener | mAnimatorEventListenerThis listener is the mechanism by which the underlying Animator causes changes to the
properties currently being animated, as well as the cleanup after an animation is
complete. |
ArrayList | mPendingAnimationsThis list holds the properties that have been asked to animate. We allow the caller to
request several animations prior to actually starting the underlying animator. This
enables us to run one single animator to handle several properties in parallel. Each
property is tossed onto the pending list until the animation actually starts (which is
done by posting it onto mView), at which time the pending list is cleared and the properties
on that list are added to the list of properties associated with that animator. |
private Runnable | mPendingSetupAction |
private Runnable | mPendingCleanupAction |
private Runnable | mPendingOnStartAction |
private Runnable | mPendingOnEndAction |
static final int | NONEConstants used to associate a property being requested and the mechanism used to set
the property (this class calls directly into View to set the properties in question). |
static final int | TRANSLATION_X |
static final int | TRANSLATION_Y |
static final int | TRANSLATION_Z |
static final int | SCALE_X |
static final int | SCALE_Y |
static final int | ROTATION |
static final int | ROTATION_X |
static final int | ROTATION_Y |
static final int | X |
static final int | Y |
static final int | Z |
static final int | ALPHA |
private static final int | TRANSFORM_MASK |
private Runnable | mAnimationStarterThe mechanism by which the user can request several properties that are then animated
together works by posting this Runnable to start the underlying Animator. Every time
a property animation is requested, we cancel any previous postings of the Runnable
and re-post it. This means that we will only ever run the Runnable (and thus start the
underlying animator) after the caller is done setting the properties that should be
animated together. |
private HashMap | mAnimatorMapThis list tracks the list of properties being animated by any particular animator.
In most situations, there would only ever be one animator running at a time. But it is
possible to request some properties to animate together, then while those properties
are animating, to request some other properties to animate together. The way that
works is by having this map associate the group of properties being animated with the
animator handling the animation. On every update event for an Animator, we ask the
map for the associated properties and set them accordingly. |
private HashMap | mAnimatorSetupMap |
private HashMap | mAnimatorCleanupMap |
private HashMap | mAnimatorOnStartMap |
private HashMap | mAnimatorOnEndMap |
Methods Summary |
---|
public android.view.ViewPropertyAnimator | alpha(float value)This method will cause the View's alpha property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(ALPHA, value);
return this;
|
public android.view.ViewPropertyAnimator | alphaBy(float value)This method will cause the View's alpha property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(ALPHA, value);
return this;
|
private void | animateProperty(int constantName, float toValue)Utility function, called by the various x(), y(), etc. methods. This stores the
constant name for the property along with the from/delta values that will be used to
calculate and set the property during the animation. This structure is added to the
pending animations, awaiting the eventual start() of the underlying animator. A
Runnable is posted to start the animation, and any pending such Runnable is canceled
(which enables us to end up starting just one animator for all of the properties
specified at one time).
float fromValue = getValue(constantName);
float deltaValue = toValue - fromValue;
animatePropertyBy(constantName, fromValue, deltaValue);
|
private void | animatePropertyBy(int constantName, float byValue)Utility function, called by the various xBy(), yBy(), etc. methods. This method is
just like animateProperty(), except the value is an offset from the property's
current value, instead of an absolute "to" value.
float fromValue = getValue(constantName);
animatePropertyBy(constantName, fromValue, byValue);
|
private void | animatePropertyBy(int constantName, float startValue, float byValue)Utility function, called by animateProperty() and animatePropertyBy(), which handles the
details of adding a pending animation and posting the request to start the animation.
// First, cancel any existing animations on this property
if (mAnimatorMap.size() > 0) {
Animator animatorToCancel = null;
Set<Animator> animatorSet = mAnimatorMap.keySet();
for (Animator runningAnim : animatorSet) {
PropertyBundle bundle = mAnimatorMap.get(runningAnim);
if (bundle.cancel(constantName)) {
// property was canceled - cancel the animation if it's now empty
// Note that it's safe to break out here because every new animation
// on a property will cancel a previous animation on that property, so
// there can only ever be one such animation running.
if (bundle.mPropertyMask == NONE) {
// the animation is no longer changing anything - cancel it
animatorToCancel = runningAnim;
break;
}
}
}
if (animatorToCancel != null) {
animatorToCancel.cancel();
}
}
NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue);
mPendingAnimations.add(nameValuePair);
mView.removeCallbacks(mAnimationStarter);
mView.postOnAnimation(mAnimationStarter);
|
public void | cancel()Cancels all property animations that are currently running or pending.
if (mAnimatorMap.size() > 0) {
HashMap<Animator, PropertyBundle> mAnimatorMapCopy =
(HashMap<Animator, PropertyBundle>)mAnimatorMap.clone();
Set<Animator> animatorSet = mAnimatorMapCopy.keySet();
for (Animator runningAnim : animatorSet) {
runningAnim.cancel();
}
}
mPendingAnimations.clear();
mPendingSetupAction = null;
mPendingCleanupAction = null;
mPendingOnStartAction = null;
mPendingOnEndAction = null;
mView.removeCallbacks(mAnimationStarter);
if (mRTBackend != null) {
mRTBackend.cancelAll();
}
|
public long | getDuration()Returns the current duration of property animations. If the duration was set on this
object, that value is returned. Otherwise, the default value of the underlying Animator
is returned.
if (mDurationSet) {
return mDuration;
} else {
// Just return the default from ValueAnimator, since that's what we'd get if
// the value has not been set otherwise
if (mTempValueAnimator == null) {
mTempValueAnimator = new ValueAnimator();
}
return mTempValueAnimator.getDuration();
}
|
public android.animation.TimeInterpolator | getInterpolator()Returns the timing interpolator that this animation uses.
if (mInterpolatorSet) {
return mInterpolator;
} else {
// Just return the default from ValueAnimator, since that's what we'd get if
// the value has not been set otherwise
if (mTempValueAnimator == null) {
mTempValueAnimator = new ValueAnimator();
}
return mTempValueAnimator.getInterpolator();
}
|
Animator.AnimatorListener | getListener()
return mListener;
|
public long | getStartDelay()Returns the current startDelay of property animations. If the startDelay was set on this
object, that value is returned. Otherwise, the default value of the underlying Animator
is returned.
if (mStartDelaySet) {
return mStartDelay;
} else {
// Just return the default from ValueAnimator (0), since that's what we'd get if
// the value has not been set otherwise
return 0;
}
|
ValueAnimator.AnimatorUpdateListener | getUpdateListener()
return mUpdateListener;
|
private float | getValue(int propertyConstant)This method gets the value of the named property from the View object.
final RenderNode node = mView.mRenderNode;
switch (propertyConstant) {
case TRANSLATION_X:
return node.getTranslationX();
case TRANSLATION_Y:
return node.getTranslationY();
case TRANSLATION_Z:
return node.getTranslationZ();
case ROTATION:
return node.getRotation();
case ROTATION_X:
return node.getRotationX();
case ROTATION_Y:
return node.getRotationY();
case SCALE_X:
return node.getScaleX();
case SCALE_Y:
return node.getScaleY();
case X:
return mView.mLeft + node.getTranslationX();
case Y:
return mView.mTop + node.getTranslationY();
case Z:
return node.getElevation() + node.getTranslationZ();
case ALPHA:
return mView.mTransformationInfo.mAlpha;
}
return 0;
|
boolean | hasActions()
return mPendingSetupAction != null
|| mPendingCleanupAction != null
|| mPendingOnStartAction != null
|| mPendingOnEndAction != null;
|
public android.view.ViewPropertyAnimator | rotation(float value)This method will cause the View's rotation property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(ROTATION, value);
return this;
|
public android.view.ViewPropertyAnimator | rotationBy(float value)This method will cause the View's rotation property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(ROTATION, value);
return this;
|
public android.view.ViewPropertyAnimator | rotationX(float value)This method will cause the View's rotationX property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(ROTATION_X, value);
return this;
|
public android.view.ViewPropertyAnimator | rotationXBy(float value)This method will cause the View's rotationX property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(ROTATION_X, value);
return this;
|
public android.view.ViewPropertyAnimator | rotationY(float value)This method will cause the View's rotationY property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(ROTATION_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | rotationYBy(float value)This method will cause the View's rotationY property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(ROTATION_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | scaleX(float value)This method will cause the View's scaleX property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(SCALE_X, value);
return this;
|
public android.view.ViewPropertyAnimator | scaleXBy(float value)This method will cause the View's scaleX property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(SCALE_X, value);
return this;
|
public android.view.ViewPropertyAnimator | scaleY(float value)This method will cause the View's scaleY property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(SCALE_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | scaleYBy(float value)This method will cause the View's scaleY property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(SCALE_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | setDuration(long duration)Sets the duration for the underlying animator that animates the requested properties.
By default, the animator uses the default value for ValueAnimator. Calling this method
will cause the declared value to be used instead.
if (duration < 0) {
throw new IllegalArgumentException("Animators cannot have negative duration: " +
duration);
}
mDurationSet = true;
mDuration = duration;
return this;
|
public android.view.ViewPropertyAnimator | setInterpolator(android.animation.TimeInterpolator interpolator)Sets the interpolator for the underlying animator that animates the requested properties.
By default, the animator uses the default interpolator for ValueAnimator. Calling this method
will cause the declared object to be used instead.
mInterpolatorSet = true;
mInterpolator = interpolator;
return this;
|
public android.view.ViewPropertyAnimator | setListener(Animator.AnimatorListener listener)Sets a listener for events in the underlying Animators that run the property
animations.
mListener = listener;
return this;
|
public android.view.ViewPropertyAnimator | setStartDelay(long startDelay)Sets the startDelay for the underlying animator that animates the requested properties.
By default, the animator uses the default value for ValueAnimator. Calling this method
will cause the declared value to be used instead.
if (startDelay < 0) {
throw new IllegalArgumentException("Animators cannot have negative start " +
"delay: " + startDelay);
}
mStartDelaySet = true;
mStartDelay = startDelay;
return this;
|
public android.view.ViewPropertyAnimator | setUpdateListener(ValueAnimator.AnimatorUpdateListener listener)Sets a listener for update events in the underlying ValueAnimator that runs
the property animations. Note that the underlying animator is animating between
0 and 1 (these values are then turned into the actual property values internally
by ViewPropertyAnimator). So the animator cannot give information on the current
values of the properties being animated by this ViewPropertyAnimator, although
the view object itself can be queried to get the current values.
mUpdateListener = listener;
return this;
|
private void | setValue(int propertyConstant, float value)This method handles setting the property values directly in the View object's fields.
propertyConstant tells it which property should be set, value is the value to set
the property to.
final View.TransformationInfo info = mView.mTransformationInfo;
final RenderNode renderNode = mView.mRenderNode;
switch (propertyConstant) {
case TRANSLATION_X:
renderNode.setTranslationX(value);
break;
case TRANSLATION_Y:
renderNode.setTranslationY(value);
break;
case TRANSLATION_Z:
renderNode.setTranslationZ(value);
break;
case ROTATION:
renderNode.setRotation(value);
break;
case ROTATION_X:
renderNode.setRotationX(value);
break;
case ROTATION_Y:
renderNode.setRotationY(value);
break;
case SCALE_X:
renderNode.setScaleX(value);
break;
case SCALE_Y:
renderNode.setScaleY(value);
break;
case X:
renderNode.setTranslationX(value - mView.mLeft);
break;
case Y:
renderNode.setTranslationY(value - mView.mTop);
break;
case Z:
renderNode.setTranslationZ(value - renderNode.getElevation());
break;
case ALPHA:
info.mAlpha = value;
renderNode.setAlpha(value);
break;
}
|
public void | start()Starts the currently pending property animations immediately. Calling start()
is optional because all animations start automatically at the next opportunity. However,
if the animations are needed to start immediately and synchronously (not at the time when
the next event is processed by the hierarchy, which is when the animations would begin
otherwise), then this method can be used.
mView.removeCallbacks(mAnimationStarter);
startAnimation();
|
private void | startAnimation()Starts the underlying Animator for a set of properties. We use a single animator that
simply runs from 0 to 1, and then use that fractional value to set each property
value accordingly.
if (mRTBackend != null && mRTBackend.startAnimation(this)) {
return;
}
mView.setHasTransientState(true);
ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
ArrayList<NameValuesHolder> nameValueList =
(ArrayList<NameValuesHolder>) mPendingAnimations.clone();
mPendingAnimations.clear();
int propertyMask = 0;
int propertyCount = nameValueList.size();
for (int i = 0; i < propertyCount; ++i) {
NameValuesHolder nameValuesHolder = nameValueList.get(i);
propertyMask |= nameValuesHolder.mNameConstant;
}
mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList));
if (mPendingSetupAction != null) {
mAnimatorSetupMap.put(animator, mPendingSetupAction);
mPendingSetupAction = null;
}
if (mPendingCleanupAction != null) {
mAnimatorCleanupMap.put(animator, mPendingCleanupAction);
mPendingCleanupAction = null;
}
if (mPendingOnStartAction != null) {
mAnimatorOnStartMap.put(animator, mPendingOnStartAction);
mPendingOnStartAction = null;
}
if (mPendingOnEndAction != null) {
mAnimatorOnEndMap.put(animator, mPendingOnEndAction);
mPendingOnEndAction = null;
}
animator.addUpdateListener(mAnimatorEventListener);
animator.addListener(mAnimatorEventListener);
if (mStartDelaySet) {
animator.setStartDelay(mStartDelay);
}
if (mDurationSet) {
animator.setDuration(mDuration);
}
if (mInterpolatorSet) {
animator.setInterpolator(mInterpolator);
}
animator.start();
|
public android.view.ViewPropertyAnimator | translationX(float value)This method will cause the View's translationX property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(TRANSLATION_X, value);
return this;
|
public android.view.ViewPropertyAnimator | translationXBy(float value)This method will cause the View's translationX property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(TRANSLATION_X, value);
return this;
|
public android.view.ViewPropertyAnimator | translationY(float value)This method will cause the View's translationY property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(TRANSLATION_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | translationYBy(float value)This method will cause the View's translationY property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(TRANSLATION_Y, value);
return this;
|
public android.view.ViewPropertyAnimator | translationZ(float value)This method will cause the View's translationZ property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(TRANSLATION_Z, value);
return this;
|
public android.view.ViewPropertyAnimator | translationZBy(float value)This method will cause the View's translationZ property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(TRANSLATION_Z, value);
return this;
|
public android.view.ViewPropertyAnimator | withEndAction(java.lang.Runnable runnable)Specifies an action to take place when the next animation ends. The action is only
run if the animation ends normally; if the ViewPropertyAnimator is canceled during
that animation, the runnable will not run.
This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate
choreographing ViewPropertyAnimator animations with other animations or actions
in the application.
For example, the following code animates a view to x=200 and then back to 0:
Runnable endAction = new Runnable() {
public void run() {
view.animate().x(0);
}
};
view.animate().x(200).withEndAction(endAction);
mPendingOnEndAction = runnable;
if (runnable != null && mAnimatorOnEndMap == null) {
mAnimatorOnEndMap = new HashMap<Animator, Runnable>();
}
return this;
|
public android.view.ViewPropertyAnimator | withLayer()The View associated with this ViewPropertyAnimator will have its
{@link View#setLayerType(int, android.graphics.Paint) layer type} set to
{@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation.
As stated in the documentation for {@link View#LAYER_TYPE_HARDWARE},
the actual type of layer used internally depends on the runtime situation of the
view. If the activity and this view are hardware-accelerated, then the layer will be
accelerated as well. If the activity or the view is not accelerated, then the layer will
effectively be the same as {@link View#LAYER_TYPE_SOFTWARE}.
This state is not persistent, either on the View or on this ViewPropertyAnimator: the
layer type of the View will be restored when the animation ends to what it was when this
method was called, and this setting on ViewPropertyAnimator is only valid for the next
animation. Note that calling this method and then independently setting the layer type of
the View (by a direct call to {@link View#setLayerType(int, android.graphics.Paint)}) will
result in some inconsistency, including having the layer type restored to its pre-withLayer()
value when the animation ends.
mPendingSetupAction= new Runnable() {
@Override
public void run() {
mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
if (mView.isAttachedToWindow()) {
mView.buildLayer();
}
}
};
final int currentLayerType = mView.getLayerType();
mPendingCleanupAction = new Runnable() {
@Override
public void run() {
mView.setLayerType(currentLayerType, null);
}
};
if (mAnimatorSetupMap == null) {
mAnimatorSetupMap = new HashMap<Animator, Runnable>();
}
if (mAnimatorCleanupMap == null) {
mAnimatorCleanupMap = new HashMap<Animator, Runnable>();
}
return this;
|
public android.view.ViewPropertyAnimator | withStartAction(java.lang.Runnable runnable)Specifies an action to take place when the next animation runs. If there is a
{@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the
action will run after that startDelay expires, when the actual animation begins.
This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate
choreographing ViewPropertyAnimator animations with other animations or actions
in the application.
mPendingOnStartAction = runnable;
if (runnable != null && mAnimatorOnStartMap == null) {
mAnimatorOnStartMap = new HashMap<Animator, Runnable>();
}
return this;
|
public android.view.ViewPropertyAnimator | x(float value)This method will cause the View's x property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(X, value);
return this;
|
public android.view.ViewPropertyAnimator | xBy(float value)This method will cause the View's x property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(X, value);
return this;
|
public android.view.ViewPropertyAnimator | y(float value)This method will cause the View's y property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(Y, value);
return this;
|
public android.view.ViewPropertyAnimator | yBy(float value)This method will cause the View's y property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(Y, value);
return this;
|
public android.view.ViewPropertyAnimator | z(float value)This method will cause the View's z property to be animated to the
specified value. Animations already running on the property will be canceled.
animateProperty(Z, value);
return this;
|
public android.view.ViewPropertyAnimator | zBy(float value)This method will cause the View's z property to be animated by the
specified value. Animations already running on the property will be canceled.
animatePropertyBy(Z, value);
return this;
|