一.使用
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); // 入口1
valueAnimator.addUpdateListener(new AnimatorUpdateListener() { // 入口2
// 持有一个IntEvaluator对象,方便下面估值的时候使用
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 获得当前动画的进度值,整型,1-100之间
int currentValue = (Integer) animator.getAnimatedValue();
Log.d(TAG, "current value: " + currentValue);
// TODO 使用中间值animator
}
});
valueAnimator.setDuration(5000).start(); // 入口3
二.源码分析
0.继承关系
class ValueAnimator extends Animator
// 定义了一些启动,结束,设置监听的基本方法.这些方法很多都是空实现(比如:start,end,cancel)
public abstract class Animator {
ArrayList<AnimatorListener> mListeners = null;
...
}
1.ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); // 入口1
public static ValueAnimator ofInt(int... values) { // 类似于工厂方法
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
public void setIntValues(int... values) {
if (mValues == null || mValues.length == 0) { // mValues默认为空
setValues(PropertyValuesHolder.ofInt("", values));
}
// New property/values/target should cause re-initialization prior to starting
mInitialized = false;
}
public static PropertyValuesHolder ofInt(String propertyName, int... values) {
return new IntPropertyValuesHolder(propertyName, values);
}
public IntPropertyValuesHolder(String propertyName, int... values) { // values==1,100
mPropertyName = propertyName;
setIntValues(values);
}
public void setIntValues(int... values) {
mValueType = int.class;
mKeyframeSet = KeyframeSet.ofInt(values); // 维护一个KeyFrame的set集合
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
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 = values[i];
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
// New property/values/target should cause re-initialization prior to starting
mInitialized = false;
}
2.valueAnimator.addUpdateListener(new AnimatorUpdateListener() // 入口2
public void addUpdateListener(AnimatorUpdateListener listener) {
mUpdateListeners.add(listener);
}
3.valueAnimator.setDuration(5000).start(); // 入口3
public ValueAnimator setDuration(long duration) {
mDuration = duration;
return this;
}
@Override
public void start() {
start(false); // 1. // scheduleAnimation(); // schedule时刻表,预定计划
}
private void start(boolean playBackwards) {
// 设置一些状态值
mPlayingBackwards = playBackwards; // false
mCurrentIteration = 0;
mPlayingState = STOPPED;
mStarted = true;
mStartedDelay = false;
mPaused = false;
AnimationHandler animationHandler = getOrCreateAnimationHandler(); // AnimationHandler:管理所有AnimationHandler
animationHandler.mPendingAnimations.add(this); // 把当前的ValueAnimator添加到链表中
if (mStartDelay == 0) {
// This sets the initial value of the animation, prior to actually starting it running
setCurrentPlayTime(0);
mPlayingState = STOPPED;
mRunning = true;
notifyStartListeners(); // 调用AnimatorListener的onAnimationStart
}
animationHandler.start(); // 2.
}
protected static ThreadLocal<AnimationHandler> sAnimationHandler =
new ThreadLocal<AnimationHandler>();
private static AnimationHandler getOrCreateAnimationHandler() {
AnimationHandler handler = sAnimationHandler.get();
if (handler == null) { // 一开始默认为null(还没设置值)
handler = new AnimationHandler();
sAnimationHandler.set(handler);
}
return handler;
}
protected static class AnimationHandler implements Runnable {
// 管理所有的ValueAnimator对象
protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
private final Choreographer mChoreographer; // Choreographer编舞者
private boolean mAnimationScheduled;
private AnimationHandler() {
mChoreographer = Choreographer.getInstance(); // Coordinates协调,坐标 the timing of animations, input and drawing.
}
public void start() {
scheduleAnimation(); // 3.
}
private boolean mAnimationScheduled; // 默认为false
// ValueAnimator的入口:大致和Choreographer的入口分析类似
private void scheduleAnimation() {
if (!mAnimationScheduled) {
// 4.
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); // action为下面run函数
mAnimationScheduled = true;
}
}
// 5.
// 该方法在scheduleAnimation被调用后回调(在Choreographer的Handler中被回调)
// Called by the Choreographer.
@Override
public void run() {
mAnimationScheduled = false;
doAnimationFrame(mChoreographer.getFrameTime());
}
// 6.
// AnimationHandler的核心代码
private void doAnimationFrame(long frameTime) {
while (mPendingAnimations.size() > 0) { // ValueAnimator的链表
ArrayList<ValueAnimator> pendingCopy =
(ArrayList<ValueAnimator>) mPendingAnimations.clone();
mPendingAnimations.clear(); // 链表的操作,清空所有item
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
anim.startAnimation(this);
}
}
...
// Now process all active animations. The return value from animationFrame()
// tells the handler whether it should now be ended
int numAnims = mAnimations.size();
for (int i = 0; i < numAnims; ++i) {
mTmpAnimations.add(mAnimations.get(i));
}
for (int i = 0; i < numAnims; ++i) {
ValueAnimator anim = mTmpAnimations.get(i);
// anim.doAnimationFrame(frameTime)一般情况下返回false,所以mEndingAnims一般没添加元素
// anim.doAnimationFrame是ValueAnimator的核心代码
// 7.
if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) { // 执行链表中所有ValueAnimator
mEndingAnims.add(anim);
}
}
mTmpAnimations.clear();
if (mEndingAnims.size() > 0) {
for (int i = 0; i < mEndingAnims.size(); ++i) {
mEndingAnims.get(i).endAnimation(this);
}
mEndingAnims.clear();
}
// If there are still active or delayed animations, schedule a future call to
// onAnimate to process the next frame of the animations.
if (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty()) {
// 11.
scheduleAnimation(); // 重新执行动画--类似递归了
}
}
}
// 7.
final boolean doAnimationFrame(long frameTime) {
final long currentTime = Math.max(frameTime, mStartTime);
// 8.
return animationFrame(currentTime);
}
boolean animationFrame(long currentTime) {
boolean done = false;
switch (mPlayingState) {
case RUNNING:
case SEEKED: // 一般情况下执行
float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
if (fraction >= 1f) {
...
done = true; // 只有当执行的时间超过1.0的时候,也就是执行完毕之后,done才会被置为true
fraction = Math.min(fraction, 1.0f);
}
if (mPlayingBackwards) { // 往回执行
fraction = 1f - fraction;
}
// 9.
animateValue(fraction); // fraction分数;一小部分
break;
}
return done;
}
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction); // 获取差值器得到当前执行的百分比
mCurrentFraction = 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) {
// 10.
mUpdateListeners.get(i).onAnimationUpdate(this); // 回调更新方法
}
}
}
private void startAnimation(AnimationHandler handler) {
initAnimation();
handler.mAnimations.add(this); // 把ValueAnimator添加到Handler的队列中
if (mStartDelay > 0 && mListeners != null) {
// Listeners were already notified in start() if startDelay is 0; this is
// just for delayed animations
notifyStartListeners();
}
}
private void endAnimation(AnimationHandler handler) {
handler.mAnimations.remove(this);
handler.mPendingAnimations.remove(this);
handler.mDelayedAnims.remove(this);
mPlayingState = STOPPED;
mPaused = false;
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners();
}
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (int i = 0; i < numListeners; ++i) {
tmpListeners.get(i).onAnimationEnd(this); // 回调结束时监听
}
}
mRunning = false;
mStarted = false;
}
三.总结
1.调用过程:如上述1-11步骤
2.实现过程主要包括三个类:ValueAnimator,ValueAnimator.AnimationHandler(static内部类),Choreographer
ValueAnimator:
成员:
/**
* The property/value sets being animated.
*/
PropertyValuesHolder[] mValues;
各种开始,停止,暂停状态
各种监听的回调链表
功能:保存当前动画的状态和在各种状态时回调对应状态的监听
AnimationHandler:看做是管理所有的ValueAnimator的链表和处理器
成员:
// ValueAnimator各种状态(预开始,开始,运行中,结束等)的链表
// The per-thread list of all active animations
/** @hide */
protected final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
// The per-thread set of animations to be started on the next animation frame
/** @hide */
protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mEndingAnims = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mReadyAnims = new ArrayList<ValueAnimator>();
// 在某个时间点在Handler中,回调run方法的"跳舞者"
private final Choreographer mChoreographer;
功能:
控制所有状态的所有ValueAnimator的状态改变和相应状态的回调方法的调用
Handler中执行run回调方法,并回调各种状态方法(UI线程中)
Choreographer 再一次说明数据才是王道!!
成员:
private final FrameHandler mHandler; // Handler
private final CallbackQueue[] mCallbackQueues; // 三个回调队列
功能:
Handler中执行回调
3.引擎为ValueAnimator.AnimationHandler(static内部类),该类持有ValueAnimator和Choreographer,由ValueAnimator进行中转,
AnimationHandler更像一个控制器,真正干活的:Choreographer("跳舞者")
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); // 入口1
valueAnimator.addUpdateListener(new AnimatorUpdateListener() { // 入口2
// 持有一个IntEvaluator对象,方便下面估值的时候使用
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator animator) {
// 获得当前动画的进度值,整型,1-100之间
int currentValue = (Integer) animator.getAnimatedValue();
Log.d(TAG, "current value: " + currentValue);
// TODO 使用中间值animator
}
});
valueAnimator.setDuration(5000).start(); // 入口3
二.源码分析
0.继承关系
class ValueAnimator extends Animator
// 定义了一些启动,结束,设置监听的基本方法.这些方法很多都是空实现(比如:start,end,cancel)
public abstract class Animator {
ArrayList<AnimatorListener> mListeners = null;
...
}
1.ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100); // 入口1
public static ValueAnimator ofInt(int... values) { // 类似于工厂方法
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
public void setIntValues(int... values) {
if (mValues == null || mValues.length == 0) { // mValues默认为空
setValues(PropertyValuesHolder.ofInt("", values));
}
// New property/values/target should cause re-initialization prior to starting
mInitialized = false;
}
public static PropertyValuesHolder ofInt(String propertyName, int... values) {
return new IntPropertyValuesHolder(propertyName, values);
}
public IntPropertyValuesHolder(String propertyName, int... values) { // values==1,100
mPropertyName = propertyName;
setIntValues(values);
}
public void setIntValues(int... values) {
mValueType = int.class;
mKeyframeSet = KeyframeSet.ofInt(values); // 维护一个KeyFrame的set集合
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
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 = values[i];
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
// New property/values/target should cause re-initialization prior to starting
mInitialized = false;
}
2.valueAnimator.addUpdateListener(new AnimatorUpdateListener() // 入口2
public void addUpdateListener(AnimatorUpdateListener listener) {
mUpdateListeners.add(listener);
}
3.valueAnimator.setDuration(5000).start(); // 入口3
public ValueAnimator setDuration(long duration) {
mDuration = duration;
return this;
}
@Override
public void start() {
start(false); // 1. // scheduleAnimation(); // schedule时刻表,预定计划
}
private void start(boolean playBackwards) {
// 设置一些状态值
mPlayingBackwards = playBackwards; // false
mCurrentIteration = 0;
mPlayingState = STOPPED;
mStarted = true;
mStartedDelay = false;
mPaused = false;
AnimationHandler animationHandler = getOrCreateAnimationHandler(); // AnimationHandler:管理所有AnimationHandler
animationHandler.mPendingAnimations.add(this); // 把当前的ValueAnimator添加到链表中
if (mStartDelay == 0) {
// This sets the initial value of the animation, prior to actually starting it running
setCurrentPlayTime(0);
mPlayingState = STOPPED;
mRunning = true;
notifyStartListeners(); // 调用AnimatorListener的onAnimationStart
}
animationHandler.start(); // 2.
}
protected static ThreadLocal<AnimationHandler> sAnimationHandler =
new ThreadLocal<AnimationHandler>();
private static AnimationHandler getOrCreateAnimationHandler() {
AnimationHandler handler = sAnimationHandler.get();
if (handler == null) { // 一开始默认为null(还没设置值)
handler = new AnimationHandler();
sAnimationHandler.set(handler);
}
return handler;
}
protected static class AnimationHandler implements Runnable {
// 管理所有的ValueAnimator对象
protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
private final Choreographer mChoreographer; // Choreographer编舞者
private boolean mAnimationScheduled;
private AnimationHandler() {
mChoreographer = Choreographer.getInstance(); // Coordinates协调,坐标 the timing of animations, input and drawing.
}
public void start() {
scheduleAnimation(); // 3.
}
private boolean mAnimationScheduled; // 默认为false
// ValueAnimator的入口:大致和Choreographer的入口分析类似
private void scheduleAnimation() {
if (!mAnimationScheduled) {
// 4.
mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); // action为下面run函数
mAnimationScheduled = true;
}
}
// 5.
// 该方法在scheduleAnimation被调用后回调(在Choreographer的Handler中被回调)
// Called by the Choreographer.
@Override
public void run() {
mAnimationScheduled = false;
doAnimationFrame(mChoreographer.getFrameTime());
}
// 6.
// AnimationHandler的核心代码
private void doAnimationFrame(long frameTime) {
while (mPendingAnimations.size() > 0) { // ValueAnimator的链表
ArrayList<ValueAnimator> pendingCopy =
(ArrayList<ValueAnimator>) mPendingAnimations.clone();
mPendingAnimations.clear(); // 链表的操作,清空所有item
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
anim.startAnimation(this);
}
}
...
// Now process all active animations. The return value from animationFrame()
// tells the handler whether it should now be ended
int numAnims = mAnimations.size();
for (int i = 0; i < numAnims; ++i) {
mTmpAnimations.add(mAnimations.get(i));
}
for (int i = 0; i < numAnims; ++i) {
ValueAnimator anim = mTmpAnimations.get(i);
// anim.doAnimationFrame(frameTime)一般情况下返回false,所以mEndingAnims一般没添加元素
// anim.doAnimationFrame是ValueAnimator的核心代码
// 7.
if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) { // 执行链表中所有ValueAnimator
mEndingAnims.add(anim);
}
}
mTmpAnimations.clear();
if (mEndingAnims.size() > 0) {
for (int i = 0; i < mEndingAnims.size(); ++i) {
mEndingAnims.get(i).endAnimation(this);
}
mEndingAnims.clear();
}
// If there are still active or delayed animations, schedule a future call to
// onAnimate to process the next frame of the animations.
if (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty()) {
// 11.
scheduleAnimation(); // 重新执行动画--类似递归了
}
}
}
// 7.
final boolean doAnimationFrame(long frameTime) {
final long currentTime = Math.max(frameTime, mStartTime);
// 8.
return animationFrame(currentTime);
}
boolean animationFrame(long currentTime) {
boolean done = false;
switch (mPlayingState) {
case RUNNING:
case SEEKED: // 一般情况下执行
float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
if (fraction >= 1f) {
...
done = true; // 只有当执行的时间超过1.0的时候,也就是执行完毕之后,done才会被置为true
fraction = Math.min(fraction, 1.0f);
}
if (mPlayingBackwards) { // 往回执行
fraction = 1f - fraction;
}
// 9.
animateValue(fraction); // fraction分数;一小部分
break;
}
return done;
}
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction); // 获取差值器得到当前执行的百分比
mCurrentFraction = 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) {
// 10.
mUpdateListeners.get(i).onAnimationUpdate(this); // 回调更新方法
}
}
}
private void startAnimation(AnimationHandler handler) {
initAnimation();
handler.mAnimations.add(this); // 把ValueAnimator添加到Handler的队列中
if (mStartDelay > 0 && mListeners != null) {
// Listeners were already notified in start() if startDelay is 0; this is
// just for delayed animations
notifyStartListeners();
}
}
private void endAnimation(AnimationHandler handler) {
handler.mAnimations.remove(this);
handler.mPendingAnimations.remove(this);
handler.mDelayedAnims.remove(this);
mPlayingState = STOPPED;
mPaused = false;
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners();
}
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (int i = 0; i < numListeners; ++i) {
tmpListeners.get(i).onAnimationEnd(this); // 回调结束时监听
}
}
mRunning = false;
mStarted = false;
}
三.总结
1.调用过程:如上述1-11步骤
2.实现过程主要包括三个类:ValueAnimator,ValueAnimator.AnimationHandler(static内部类),Choreographer
ValueAnimator:
成员:
/**
* The property/value sets being animated.
*/
PropertyValuesHolder[] mValues;
各种开始,停止,暂停状态
各种监听的回调链表
功能:保存当前动画的状态和在各种状态时回调对应状态的监听
AnimationHandler:看做是管理所有的ValueAnimator的链表和处理器
成员:
// ValueAnimator各种状态(预开始,开始,运行中,结束等)的链表
// The per-thread list of all active animations
/** @hide */
protected final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
// The per-thread set of animations to be started on the next animation frame
/** @hide */
protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mEndingAnims = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mReadyAnims = new ArrayList<ValueAnimator>();
// 在某个时间点在Handler中,回调run方法的"跳舞者"
private final Choreographer mChoreographer;
功能:
控制所有状态的所有ValueAnimator的状态改变和相应状态的回调方法的调用
Handler中执行run回调方法,并回调各种状态方法(UI线程中)
Choreographer 再一次说明数据才是王道!!
成员:
private final FrameHandler mHandler; // Handler
private final CallbackQueue[] mCallbackQueues; // 三个回调队列
功能:
Handler中执行回调
3.引擎为ValueAnimator.AnimationHandler(static内部类),该类持有ValueAnimator和Choreographer,由ValueAnimator进行中转,
AnimationHandler更像一个控制器,真正干活的:Choreographer("跳舞者")