从源码角度理解android动画Inte

?

小编有话说

做过android动画的人对Interpolator应该不会陌生,这个类主要是用来控制android动画的执行速率,一般情况下,如果我们不设置,动画都不是匀速执行的,系统默认是先加速后减速这样一种动画执行速率。

android通过Interpolator类来让我们自己控制动画的执行速率,还记得上一篇博客中我们使用属性动画实现的旋转效果吗?在不设置Interpolator的情况下,这个动画是先加速后减速,我们现在使用android系统提供的类LinearInterpolator来设置动画的执行速率,LinearInterpolator可以让这个动画匀速执行,我们来看一个案例,我们有两个TextView重叠放在一起,点击旋转按钮后这两个TextView同时执行旋转动画,不同的是一个设置了LinearInterpolator,而另外一个什么都没有设置,代码如下:

codeavrasm=class=hljsLinearInterpolatorll=newLinearInterpolator();ObjectAnimatoranimator=ObjectAnimator.ofFloat(tv,rotation,0f,f);animator.setInterpolator(ll);animator.setDuration();animator.start();ObjectAnimatoranimator2=ObjectAnimator.ofFloat(tv2,rotation,0f,f);animator2.setDuration();animator2.start();/code

效果图如下:

现在我们可以很清楚的看到这里的差异,一个TextView先加速后减速,一个一直匀速运动。

这就引起了我的好奇,究竟LinearInterpolator做了什么,改变了动画的执行速率。这里我们就要看看源码了。当我们调用animator.setInterpolator(ll);的时候,调用的是ValueAnimator方法中的setInterpolator方法,源码如下:

codeclass=hljscs=publicvoidsetInterpolator(TimeInterpolatorvalue){if(value!=null){mInterpolator=value;}else{mInterpolator=newLinearInterpolator();}}/code

我们看到这里有一个mInterpolator变量,如果我们不执行这个方法,那么mInterpolator的默认值是多少呢?我们找到了这样两行代码:

codeclass=hljsjava=//ThetimeinterpolatortobeusedifnoneissetontheanimationprivatestaticfinalTimeInterpolatorsDefaultInterpolator=newAccelerateDecelerateInterpolator();

privateTimeInterpolatormInterpolator=sDefaultInterpolator;/code

这下明朗了,如果我们不设置,那么系统默认使用AccelerateDecelerateInterpolator,AccelerateDecelerateInterpolator又是什么呢?继续看源码:

codeclass=hljsjava=publicclassAccelerateDecelerateInterpolatorextendsBaseInterpolatorimplementsNativeInterpolatorFactory{publicAccelerateDecelerateInterpolator(){}

SuppressWarnings({UnusedDeclaration})publicAccelerateDecelerateInterpolator(Contextcontext,AttributeSetattrs){}publicfloatgetInterpolation(floatinput){return(float)(Math.cos((input+1)*Math.PI)/2.0f)+0.5f;}/**

hide*/

OverridepubliclongcreateNativeInterpolator(){returnNativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();}}/code

这里的一个核心函数就是getInterpolation,使用了反余弦函数,input传入的值在0-1之间,因此这里返回值的变化速率就是先增加后减少,对应的动画执行速率就是先增加后减速。有兴趣的童鞋可以使用MatLab来画一下这个函数的图像。而当我们实现了LinearInterpolator之后,情况发生了变化:

codeclass=hljsjava=publicclassLinearInterpolatorextendsBaseInterpolatorimplementsNativeInterpolatorFactory{publicLinearInterpolator(){}publicLinearInterpolator(Contextcontext,AttributeSetattrs){}publicfloatgetInterpolation(floatinput){returninput;}/**

hide*/

OverridepubliclongcreateNativeInterpolator(){returnNativeInterpolatorFactoryHelper.createLinearInterpolator();}}/code

这里干净利落直接返回了input,没有经过任何计算。input返回的值是均匀的,因此动画得以匀速执行。看到这里,大家应该就明白了,如果我们想要控制动画的执行速率,应该重写getInterpolation方法就能实现。为了证实我们的猜想,我们继续看源码。

大部分时候,我们使用的系统提供的各种各样的**Interpolator,比如上文说的LinearInterpolator,这些类都是继承自Interpolator,而Interpolator则实现了TimeInterpolator接口,我们来看看一个继承结构图:

那么这个终极大BZ喎?







































北京哪个看白癜风的医院好
北京治疗白癜风到那家医院



转载请注明:http://www.gslnbdf.com/azfz/azfz/1476.html