1.2 动画流程与原理

less than 1 minute read

1.2.1 属性动画

  • ValueAnimator动画本质是帧刷新时, 提供相关刷新回调, 让业务可以调整View的属性
  • object(属性动画)必须要提供setXxx方法
  • TimeInterpolator(时间插值器), 根据时间的百分比来计算出当前属性值改变的百分比
  • TypeEvaluator(类型估值算法), 根据当前属性改变的百分比来计算改变后的属性值
ObjectAnimator.start()
-> ValueAnimator.start()
-> animationHandler.start()
-> AnimationHandler.scheduleAnimation()
// =======Choreographer流程, 参考Choreographer原理=======
-> Choreographer.postCallback()
-> postCallbackDelayed()
-> postCallbackDelayedInternal()
-> scheduleFrameLocked()
-> scheduleVsyncLocked()
-> DisplayEventReceiver.scheduleVsync()
-> onVsync()
-> doFrame(
-> doCallbacks()
// ==================
-> animationHandler.run()
-> doAnimationFrame()
-> animateBasedOnTime()
    -> animateValue()
      -> PropertyValuesHolder#calculateValue() -> PropertyValuesHolder#setupValue(), 找到getXxxx方法
    -> PropertyValuesHolder#setAnimatedValue(target);修改属性...

1.2.2 帧动画

  • 使用: 在drawable使用animation-list创建动画xml, AnimationDrawable animationDrawable = (AnimationDrawable) iv.getBackground(), View#setBackgroundDrawable(animationDrawable), 最后,animationDrawable#start()启动帧动画

  • 源码分析

    • View#setBackgroundDrawable(animationDrawable), 注册Drawable#Callback, 并由View实现Callback#scheduleDrawable(), -> mChoreographer#postCallbackDelayed(runnable),而runnable则由AnimationDrawable实现 -> nextFrame(), 又跑了次setFrame()
    • animationDrawable#start() -> AnimationDrawable#setFrame(), 其包含
      • AnimationDrawable#selectDrawable()刷新当前帧
      • Drawable#scheduleSelf() -> Callback#scheduleDrawable()即在when的时间内刷新

1.2.3 补间动画

  • 使用: rotateAnimation = (RotateAnimation)AnimationUtils#loadAnimation(this, R.anim.rotate), View#startAnimation(rotateAnimation)
  • 源码分析
    • View#startAnimation(rotateAnimation)包含
      • View#setAnimation(), 设置当前动画
      • View#invalidate() -> View#draw() -> View#applyLegacyAnimation() //有动画则执行
        • Animation#initialize()//初始化View和父View宽高
        • Transformation t = parent#getChildTransformation() //新建Transformation对象
        • Animation#getTransmation()
          • applyTransformation() -> Transformation#getMatrix().setRotate()
      • 回到View#draw() -> Canvas#translate()

1.2.4 属性动画与View动画的区别

  • 属性动画作用于View和Object
  • 属性动画修改View属性而View动画只修改大小位置, 属性不变