?
小编有话说
做过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喎?北京哪个看白癜风的医院好北京治疗白癜风到那家医院