android8.0属性动画原理分析

补间动画只是改变了View的视觉效果,而不会真正去改变View的属性。

如,将屏幕左上角的按钮 通过补间动画 移动到屏幕的右下角

点击当前按钮位置(屏幕右下角)是没有效果的,因为实际上按钮还是停留在屏幕左上角,补间动画只是将这个按钮绘制到屏幕右下角,改变了视觉效果而已。

image

ValueAnimator主要有三种估值器(TypeEvaluator)

ValueAnimator.ofFloat()采用默认的浮点型估值器(FloatEvaluator)

ValueAnimator.ofInt()采用默认的整型估值器(IntEvaluator)

ValueAnimator.ofObject()需要自己写估值器

ValueAnimator 类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;

ObjectAnimator 类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接对对象属性进行操作;

image

ObjectAnimator也可以实现补间动画的效果,通过改变这些参数,需要有get/set方法

image

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

你可能感兴趣的:(android8.0属性动画原理分析)