本篇文章主要介绍了"打造简易NineoldAndroids动画库,深入理解Android动画原理",主要涉及到队列,Exception,Git,Activity方面的内容,对于Android开发感兴趣的同学可以参考一下:
简介NineoldAndroids是Github上一个着名的动画库,简单来说,NineOldAndroids是一个向下兼容的动画库,主要是使低于API 11的系...
简介
NineoldAndroids是Github上一个着名的动画库,简单来说,NineOldAndroids是一个向下兼容的动画库,主要是使低于API 11的系统也能够使用View的属性动画。

网上已经有一些文章,介绍了这个库的设计,包括类结构和思想,例如
NineOldAnimations 源码解析
NineoldAndroids动画库源码分析
上面两篇文章都比较详细的介绍了NineoldAndroids的源码,可以说为大家看源码带来很大的方便。
那为什么我还要写这篇文章呢?
我们来看NineoldAndroids的类结构图:

因为NineoldAndroids的类结构比较复杂,即使单纯看上面两篇文章,也可能把人搞糊涂。
本篇文章将剥离NineoldAndroids的具体细节,尝试只是显示其核心功能,也就是说写出一个简易的NineoldAndroids,并且在这个过程当中,了解Android实现动画的原理和思想。
一理通百理明,与君共勉。
开篇说明
1、本动画库以Int类型的属性值为例子,实现了Android库中ValueAnimator的功能,不了解ValueAnimator使用方式的朋友,可以参考这篇文章
2、大部分代码由NineoldAndroids中抽取,剥去一些不必要的实现细节,例如delayStart()方法等
3、ValueAnimator与ObjectAnimator有所区别,本库还没有实现ObjectAnimator。ObjectAnimator是继承自ValueAnimator,本质是通过ValueAnimator计算出的值,去更新View的属性。
现在我们先来看看该动画库的使用:
publicclassMainActivityextendsActivity {
TextView mTextView;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Activity_main);
mTextView = (TextView) findViewById(R.id.mtext);
//Value动画,设置目标值为3000
CValueAnimator valueAnimator = CValueAnimator.ofInt(1000,2000,3000);
//设置动画时间
valueAnimator.setDuration(4000);
valueAnimator.addUpdateListener(new CValueAnimator.AnimatorUpdateListener() {
@OverridepublicvoidonAnimationUpdate(CValueAnimator animation) {
//将动画值,更新到textView
mTextView.setText(animation.getAnimatedValue() + "");
mTextView.setTranslationY((Integer) animation.getAnimatedValue());
mTextView.invalidate();
}
});
//启动动画
valueAnimator.start();
}
}
使用方式和NineoldAndroids完全一样,也和Android原生的方式一样,对于使用过动画效果的朋友来说,应该非常简单。
类设计图
首先来看类设计图,这图相比原来的NineoldAndroids,做了很多精简,只是希望大家更加容易看懂NineoldAndroids的本质。

在进行下一步的分析之前,我们先来了解一下一些核心的类以及它们的作用。
- CValueAnimator : 该类是 Animator 的子类,实现了动画的整个处理逻辑,也是最为核心的类;
- TimeInterpolator : 时间插值器,它的作用是根据时间流逝的百分比来计算出当前属性值改变的百分比,系统预置的有 LinearInterpolator(线性插值器:匀速动画)、AccelerateDecelerateInterpolator(加速减速插值器:动画两头慢中间快)和 DecelerateInterpolator(减速插值器:动画越来越慢)等;
- CTypeEvaluator : TypeEvaluator 的中文翻译为类型估值算法,它的作用是根据当前属性改变的百分比来计算改变后的属性值,系统预置的有 IntEvaluator(针对整型属性)、FloatEvaluator(针对浮点型属性);
- CPropertyValuesHolder : PropertyValuesHolder 是持有目标属性 Property、setter 和 getter 方法、以及 KeyFrameSet 的类;
- CKeyFrame : 一个 keyframe 对象由一对 time / value 的键值对组成,可以为动画定义某一特定时间的特定状态,Animator 传入的一个个参数映射为一个个 keyframe,存储相应的动画的触发时间和属性值;
- CKeyFrameSet : 存储一个动画的关键帧集合;
动画流程解析
1、动画初始化
在调用start()方法之前,我们使用
CValueAnimator valueAnimator = CValueAnimator.ofInt(1000,2000,3000);
做了动画的初始化工作,那么我们具体做了上面呢?
1.1、关键帧
简单而言,就是把传入的属性值,例如例子中是1000,2000,3000,封装成关键帧对象CKeyFrame。
所谓关键帧,就是在动画过程中一定要出现的帧。
我们知道,所谓动画也不可能是完全连续的,肯定会有一些间隔,只是间隔小于人眼视觉暂留时间,所以看起来就是连续的了。
所以从1000-2000这个过程,也不可能是完全连续的,也许是1000,1100,…1900,2000
其中一些帧就被丢失了,绝对不能丢失的帧,称为关键帧。
关键帧保留两个属性,一个是该帧所在的时间(其实是一个百分比),一个是帧值。