Android 动画之Animation原理

xiaoxiao2021-02-28  105

animation.startAnimation之后,会触发invalidate(true),接着调用invalidateInternal,然后调用invalidateChild,子View根据存储的parent层层上传,最后调用DectorView的invalidateChild,二DectorView的invalidateChild是实现在ViewRootImpl(同样实现了ViewParent)(最后返回null,从而使子View的invalidateInternal跳出循环),然后跳转至schuduleTraversals,里面有个runnable(mTraversalRunnable),run方法中的doTraversal,再跳转至performTraversals,这里面有三个方法performMeasure,performLayout,performDraw --> draw(boolean fullRedrawNeeded) --> drawSoftware() --> mView.draw(canvas),跳转至View中的dispatchDraw,其实现在ViewGroup中,跳转至ViewGroup中的dispatchDraw:首先查看是否有AnimationListener,若有调用onAnimationStart;开始绘画子View(drawChild);然后跳转至View的draw(canvas, this, drawingTime):调用applayLegacyAnimation(),并获取返回值赋给more;跳转至applayLegacyAnimation,触发View中回调onAnimationStart,调用Animation.getTransformation(drawTime, transformtion, 1f),然后跳转至getTransformation(currentTime, outTransformation),首先计算执行动画的比例normaliizedTime =(currentTime - (mStartTime + startOffset)) / duration,如果比例不为1,则动画未执行完,每个时刻产生的比例再传入插值器进行计算 interpolatedTime = mInterpolator.getInterpolation(normaliizedTime ),然后再调用每个animation实现的applyTransformation(interpolatedTime, outTransformation),将变换后的矩阵再传给outTransformation。如果normaliizedTime = 1f,则返回值more=false,动画结束。现在回到View的applayLegacyAnimation中,more = true时,会执行parent.invalidate,刷新View,再次回到最开始的刷新View的过程。现在回到View的draw(canvas, this, drawingTime),根据transformation.getMatrix()获取更改后的矩阵,然后使用cavas.concat(transformToApply.getMatrix())更新View的位置,产生动画效果。如果动画结束,返回值more=true,此时在View的draw(canvas, this, drawingTime)会调用ViewGroup的finishAnimatingView(this, animation),如果animation已经start,则会调用View的onAnimationEnd。如果getFillAfter返回false,则会调用animation.clear(),使view返回原始位置,如果要是其动画后位置不变,这设置setFillAfter(true)。

参考文章:

https://blog.csdn.net/u010019468/article/details/73469410

转载请注明原文地址: https://www.6miu.com/read-2600219.html

最新回复(0)