现在的位置: 首页 > 综合 > 正文

framework 之 Animator

2017年12月15日 ⁄ 综合 ⁄ 共 2620字 ⁄ 字号 评论关闭

一、前言:

        之前有篇文章讲解了Animation动画,但是自从4.0后,Google引入了新的动画框架:Animator,它与Animation的区别在于,Animator是逐帧动画,而Animation是对整个view进行了透明、位移等变化;显然,逐帧动画性能更高,Animator的源码在SDK / android / animation 下,下面来看一张UML图,描述了主要的几个文件这间的关系:

从图中可以看出,Animator是基于Keyframe即关键帧来实现动画效果的。

二、源码讲解:

2.1 抽象类Animator及其子类

Animator是个抽象类,只定义了一些方法,而实现这些方法的主要在ValueAnimator和ObjectAnimator中,其中,ObjectAnimator里面有些方法是通过super.xxx来调用ValueAnimator里的方法来执行。

2.2 PropertyValuesHolder类

不论是ValueAnimator还是ObjectAnimator,都需要通过PropertyValuesHolder类来设置/获取动画的属性值(Integer, Float),PropertyValuesHolder中会去调用native代码,

    native static private int nGetIntMethod(Class targetClass, String methodName);
    native static private int nGetFloatMethod(Class targetClass, String methodName);
    native static private void nCallIntMethod(Object target, int methodID, int arg);
    native static private void nCallFloatMethod(Object target, int methodID, float arg);

之所以需要借助native代码,获取Int或Float的方法,在这个类的开头有解释:

    // We try several different types when searching for appropriate setter/getter functions.
    // The caller may have supplied values in a type that does not match the setter/getter
    // functions (such as the integers 0 and 1 to represent floating point values for alpha).
    // Also, the use of generics in constructors means that we end up with the Object versions
    // of primitive types (Float vs. float). But most likely, the setter/getter functions
    // will take primitive types instead.
    // So we supply an ordered array of other types to try before giving up.
    private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
            Double.class, Integer.class};
    private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
            Float.class, Double.class};
    private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class,
            Float.class, Integer.class};

大意是:尝试几种不同的类型来寻找合适的setter/getter函数。调用者可能所给的值的类型不符合默认的setter/getter方法(如整数0和1在透明色中用浮点数来表示)。此外,使用通用的构造函数,也意味着我们最终原始类型的对象版本(Float与float),不过通常我们用原始类型来代替setter/getter方法。

说白了,就是底层不同类型的setter/getter方法实现可能导致值在表示意义上的不同,上面说的,透明的范围是0到1,但是当值是0和1时,既可用浮点数来表示,也可用整数来表示。

2.3 KeyframeSet、FloatKeyframeSet和IntKeyframeSet

一个动画效果,可能只有一帧,也可能有一组连续或并发的帧来显示动画,在动画的世界里,无非就是int, float或object(如改变XY轴坐标值用int;改变透明值用float等),因此,在动画开始前,需要将这些动画的属性值保存起来供动画显示过程中来用,当然,虽然图中没有写,不过,在Keyframe中有写,即Interpolater,插补器来控件速率变化。

2.4 Keyframe

这个就是动画单帧属性的最小集合,定义了用int, float还是object来表示,以及Interpolater等基本信息。

2.5 动画核心文件

核心文件有两个,一个就是ValueAnimator,在这个里面,可以读取动画所有帧的信息,动画是否重复,startAnimation启动动画,动画是由AnimationThread来完成,而它就是第二个核心文件,它需要子类实现preAnimation()和postAnimation()两个方法,否则不会真正的动起来。这个的实现,一般我们不需要关心,我们只需要了解这么一个流程即可。

三、总结

例子我就不写了,网上很多,Android自带的例子也有使用这个的,所以,大家只需要学习怎么去使用就行。

这篇文件写的不太深,因为,我也没怎么使用Animator,毕竟,简单的动画,不需要考虑性能的,用用Animation就行了,当动画复杂了,要考虑性能,用户UI体验友好时,那么就需要用Animator来好好设计了。

我也希望有大家与我一起来交流这个,大家平时使用Animator有没有好的心得体会,也可以分享。

 

抱歉!评论已关闭.