Android Framework--系统动画

这里之所以要说“系统”动画,是为了跟APP开发中的动画区分开,注意它们的原理是一样的,用到的都是android.view.animation.Animation类,这里主要从以下两个方面来区分出“系统”动画:动画由谁来施加和步进动画的目标什么是系统动画做过APP开发的童鞋都知道下面知识点:Activity切换的时候有“切换动画”,可以自行定制窗口切换的时候有“窗口动画
摘要由CSDN通过智能技术生成

拼接转屏动画矩阵这里之所以要说“系统”动画,是为了跟APP开发中的动画区分开,注意它们的原理是一样的,用到的都是android.view.animation.Animation类,这里主要从以下两个方面来区分出“系统”动画:

  1. 动画由谁来施加和步进
  2. 动画的目标

本文贴出的代码来源于Android N。


什么是系统动画

做过APP开发的童鞋都知道下面知识点:

  • Activity切换的时候有“切换动画”,可以自行定制
  • 窗口切换的时候有“窗口动画”,可以自行定制
  • 转屏的时候有“转屏动画”,由系统决定,不可定制

这里提及的三种动画,我在这里称之为“系统动画”,相比平常APP开发中施加到View上的“补间动画”,根据给出的两点标准,来看下它们的区别:

  1. 动画由谁来施加和步进
    系统动画:框架来施加和步进,即system_server进程
    补间动画:应用进程来施加和步进

  2. 动画的目标
    系统动画:整个窗口绘制出的内容,即view tree绘制出的内容
    补间动画:具体的View

不难看出,之所以用“系统”这个词,是因为系统对这些动画占据了主导权。根据这里描述的区别,可以得出一个结论:
系统动画如果出现卡顿,责任在于system_server进程,跟应用进程无关,因为应用进程跟系统动画的步进没有直接关系。
如果APP开发童鞋还在为某个切换动画或者窗口动画卡顿而苦恼,请注意,不是你们的锅!!!当然,如果因为APP乱跑导致整个系统很卡,进而影响系统动画,那又是另外一回事。


Animation原理

这里简单讲一下,所谓动画,就是以渐进的方式来呈现目标状态的改变。

那么渐进以什么为维度?很显然就是时间。时间的粒度是多大?以60fps为例,每16ms刷新一次目标的状态即可。

Animation动画就这么四种:

  • 位移(TranslateAnimation)
  • 缩放(ScaleAnimation)
  • 旋转(RotateAnimation)
  • 透明度(AlphaAnimation)

举个简单例子,比如有个透明度动画,要求目标的透明度从fromAlpha变为toAlpha,时长为duration,开始的时间为startTime,下面从数学的角度解释下状态渐进的过程:即到了一个刷新状态的时间点currentTime,求目标的透明度currentAlpha。

这个问题类似于小明从A点跑到B点,告诉你耗时,问你某个时间小明的位置。

讨论一个最简单的情形,这个过程是匀速的,那么可以得到:

v = (toAlpha - fromAlpha) / duration
elapsedTime = currentTime - startTime
currentAlpha = fromAlpha + v * elapsedTime
             = fromAlpha + (toAlpha - fromAlpha) * (currentTime - startTime) / duration

利用这个公式,每16ms计算出当前的状态并刷新,就能看到一种渐进的透明度变化的效果。

要是不匀速怎么破?比如我就想要前半段变化快一点,后半段变化慢一点。把上面最后的公式改一下:

elapsedTimePercent = (currentTime - startTime) / duration
currentAlpha = fromAlpha + (toAlpha - fromAlpha) * f(elapsedTimePercent)

上述f(x)是一个函数,对于匀速变化而言,f(x) = x。那么如果想定制变化率,问题就转化为定制f(x)函数。这个f(x)函数负责将elapsedTimePercent(逝去时间百分比)映射为一个新的值,称之为差值器(Interpolator),定义如下:

/**
 * A time interpolator defines the rate of change of an animation. This allows animations
 * to have non-linear motion, such as acceleration and deceleration.
 */
public interface TimeInterpolator {
   
    /**
     * Maps a value representing the elapsed fraction of an animation to a value that represents
     * the interpolated fraction. This interpolated value is then multiplied by the change in
     * value of an animation to derive the animated value at the current elapsed animation time.
     *
     * @param input A value between 0 and 1.0 indicating our current point
     *        in the animation where 0 represents the start and 1.0 represents
     *        the end
     * @return The interpolation value. This value can be more than 1.0 for
     *         interpolators which overshoot their targets, or less than 0 for
     *         interpolators that undershoot their targets.
     */
    float getInterpolation(float input);
}

现在我们就知道给定下面几个元素,就可以启动一个动画:

  • 起始状态
  • 结束状态
  • 动画时长
  • 差值器

然后在每个刷新的时间点计算当前的状态值,称之为动画的步进,直到时间结束。那么,如果负责动画步进的人没有及时进行状态刷新,比如32ms才刷新一次,肉眼就会感觉到突兀,也就是常说的动画卡顿。

还有个问题是,为什么Animation只支持上述的四种动画?

从数学的角度来看,位移、缩放以及旋转的原理是矩阵(Matrixÿ

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值