A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

1、概述

Android中想做很炫酷的动画效果,相信在很多时候你都可以选择使用属性动画,关于属性动画如何使用,我们已经很详细的写过两篇博客讲解。如果你还不了解,请参考:

Android 属性动画(Property Animation) 完全解析 (上)

Android 属性动画(Property Animation) 完全解析 (下)

本篇博客将分析属性动画的实现源码,带你深入的了解Android属性动画的内部实现机制。如果你经常用属性动画,但又一直没有去查看其源码实现,没关系,请往下看。

2、分析前的猜想

在源码分析之前,我们需要有一个明确的思路,例如:源码的入口的选择、甚至对其实现进行简单的猜测,源码分析相当于一个验证的过程,带着一个目标去看源码,这样的话,分析和理解起来更为方便。

对于实现属性动画,最常用的类就是ObjectAnimator了,只需要简单的设置目标view,属性,以及目标值等必要属性,调用一下start();我们的动画就完成了。

类似如下代码:


[java] view plaincopyfile:///D:/Program/WizNote/temp/991fdd3d-1292-49a6-a92a-a4428ad3af17_128_files/8e4a1685-0717-433d-a162-2875c3d340a3.png


  • ObjectAnimator  
  •   .ofInt(target,propName,values[])  
  •   .setInterpolator(LinearInterpolator)  
  •   .setEvaluator(IntEvaluator)  
  •   .setDuration(500)  
  •   .start();  


上述代码很好理解吧,设置动画作用的view,作用的属性,动画开始、结束、以及中间的任意个属性值;

然后是设置插值器,当然了插值器这个词比较难理解,我要是说例如:AccelerateInterpolator、LinearInterpolator

然后设置估值算法,这个看名字挺高端,其实内部实现尤其简单:  return (int)(startInt + fraction * (endValue - startInt)); 开始值,加上当前的属性改变的百分比*(结束-开始)

    当然了,这个百分比是fraction ,其实就是上面的插值器算出来的。比如线性插值器:fraction 值就是currentTime - mStartTime) / mDuration,动画的运行时间/总设置时间。

然后是设置动画事件,

最后start()。

好了,现在我想问个问题,根据上面这些参数,如果我要你设计个属性动画框架,你怎么做?

这个嘛,好整,拿到上述参数之后,start()中,开启一个定时器,去执行一个任务;在任务内部,根据Interpolator计算出来的fraction,交给Evaluator,得到属性当前应该设置的值,然后反射设置tagert的指定属性,ok,奏事这么简单。嗯,大体上应该就是这样,当然了,源码的实现肯定复杂很多,但是万变不离其宗,所以接下来的源码阅读,就是去验证我们的这个答案。

3、源码分析

好了,猜想完了,我们就得进入验证阶段了~~

那么,我们源码的入口就是上述代码了,不过貌似上述代码调用了好几个方法,but,我觉得start之前的代码,无法是初始化实例,设置一些成员变量。

首先我们看ofInt,这里为了简单,我们的ofInt中的values参数,默认就一个,类似 .ofInt(view, "translationX", 300) ;

1、ofInt
[java] view plaincopyfile:///D:/Program/WizNote/temp/991fdd3d-1292-49a6-a92a-a4428ad3af17_128_files/8e4a1685-0717-433d-a162-2875c3d340a3.png


  • public static ObjectAnimator ofInt(Object target, String propertyName, int... values) {  
  •         ObjectAnimator anim = new ObjectAnimator(target, propertyName);  
  •         anim.setIntValues(values);  
  •         return anim;  
  •     }  


首先调用ObjectAnimator的构造方法传入了一个target和propName,估计就是创建对象,然后旧路下target和propName,简单看下


[java] view plaincopyfile:///D:/Program/WizNote/temp/991fdd3d-1292-49a6-a92a-a4428ad3af17_128_files/8e4a1685-0717-433d-a162-2875c3d340a3.png


  • private ObjectAnimator(Object target, String propertyName) {  
  •        mTarget = target;  
  •        setPropertyName(propertyName);  
  •    }  
  • public void setPropertyName(String propertyName) {  
  •       //...  
  •        mPropertyName = propertyName;  
  •       mInitialized = false;  
  •    }


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马