补间动画只是改变了View的视觉效果,而不会真正去改变View的属性。
如,将屏幕左上角的按钮 通过补间动画 移动到屏幕的右下角
点击当前按钮位置(屏幕右下角)是没有效果的,因为实际上按钮还是停留在屏幕左上角,补间动画只是将这个按钮绘制到屏幕右下角,改变了视觉效果而已。
ValueAnimator主要有三种估值器(TypeEvaluator)
ValueAnimator.ofFloat()采用默认的浮点型估值器(FloatEvaluator)
ValueAnimator.ofInt()采用默认的整型估值器(IntEvaluator)
ValueAnimator.ofObject()需要自己写估值器
ValueAnimator 类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;
ObjectAnimator 类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接对对象属性进行操作;
ObjectAnimator也可以实现补间动画的效果,通过改变这些参数,需要有get/set方法
AnimationHandler:: MyFrameCallbackProvider::postFrameCallback(FrameCallback)
->Choreographer.postFrameCallback()
->Choreographer.postFrameCallbackDelayed()
->Choreographer. postCallbackDelayedInternal()
private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, longdelayMillis) {
synchronized (mLock) {
final long now =SystemClock.uptimeMillis();
final long dueTime = now +delayMillis;//callback到达时间
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action,token);//存到队列中
if (dueTime <= now) {
scheduleFrameLocked(now);
} else {
Message msg =mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg,dueTime);
}
}
}
Choreographer. scheduleFrameLocked()
->Choreographer. scheduleVsyncLocked()
->DisplayEventReceiver.scheduleVsync() //安排接收Vsync信号,如有Vsync信号过来会调用到FrameDisplayEventReceiver. onVsync()
->FrameDisplayEventReceiver. onVsync()
->FrameDisplayEventReceiver. run()
->Choreographer. doFrame()
->doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
->CallbackRecord.run()
->((FrameCallback)action).doFrame(frameTimeNanos);
->AnimationHandler::mFrameCallback. doFrame()
->AnimationHandler .doAnimationFrame()
->callback.doAnimationFrame(frameTime)
->ValueAnimator. doAnimationFrame()
->ValueAnimator. animateBasedOnTime()
->ValueAnimator. animateValue()
-> PropertyValuesHolder. calculateValue(fraction) //在这里计算当前时间的动画值
void animateValue(float fraction){
fraction =mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
int numValues = mValues.length;//[ValueAnimator](https://www.jianshu.com/writer)这个值为1
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);// ValueAnimator计算mValues[0]
}
if (mUpdateListeners != null) {
int numListeners =mUpdateListeners.size();
for (int i = 0; i < numListeners;++i) {
mUpdateListeners.get(i).onAnimationUpdate(this);//回调
}
}
}
获取值
public Object getAnimatedValue() {
if (mValues != null && mValues.length> 0) {
returnmValues[0].getAnimatedValue();
}
// Shouldn't get here; should alwayshave values unless ValueAnimator was set up wrong
return null;
}
ObjectAnimator介绍
public static ObjectAnimator ofInt(T target, Property property, int...values) {
……
}
有多少个属性值变化,mValues也就有多少个值
ObjectAnimator. animateValue()除了调用ValueAnimator.animateValue去计算动画值,也会调用对象的set方法来设置属性值
void animateValue(float fraction) {
final Object target = getTarget();
if (mTarget != null && target== null) {
// We lost the target reference,cancel and clean up. Note: we allow null target if the
/// target has never been set.
cancel();
return;
}
super.animateValue(fraction);
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i){
mValues[i].setAnimatedValue(target);//反射调用get方法
}
}
参考:
https://www.jianshu.com/p/2412d00a0ce4