位移动画有多种时间插值算法,比如我们常用的有AccelerateDecelerateInterpolator、AccelerateInterpolator、DecelerateInterpolator等,这些插值算法是为了给平移动画添加各种效果,加速减速、加速、减速等,这里举个例子。
AccelerateDecelerateInterpolatorinterpolator = new AccelerateDecelerateInterpolator();
TranslateAnimation translateAnim2 = new TranslateAnimation(0,-300,0,-500);
translateAnim2.setDuration(600);
translateAnim2.setInterpolator(interpolator);
translateAnim2.setFillAfter(true);
mImageView.startAnimation(translateAnim2);
这里是让ImageView进行平移动画,同时,平移的效果是先加速,再减速。
那么,插值是如何让平移动画先加速再减速的呢?
首先,系统会将所有的动画时间平均划分到(0,1)这个范围内,0就是动画开始的时间,1就是动画结束的时间,那么,既然将时间划分成这个范围,也就意味着将动画移动长度划进行了这样一个划分,比如现在插值input为 0.2,我用公式计算得到一个值interpolatedTime 为0.3,那么我就让这个View的x坐标值运动到mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime),mFromXDelta 为运动起始x坐标,mToXDelta为运动终点x坐标,那这样的话,就运动了总长度的0.3,一直到interpolatedTime 的值为1,整个动画就结束了。
看一下DecelerateInterpolator的算法,(1.0f - (1.0f - input) * (1.0f - input)),这是一个自变量范围在[0,1]、函数值范围也在[0,1]的连续函数,本人了解自变量就是总时间的比例(取值为%0,100%),函数值就是运动长度的比例(取值为%0,100%)。其函数图:
很明显了,函数的斜率其实就是速度,如图,函数的斜率是不断减小的,于是产生了减速的效果。那么,写一个自己的时间插值只需用满足:
1.函数是连续的,如果不连续,动画效果将不会连续
2.自变量范围[0,1],自变量的值是系统生成的
3.函数值域为[0,1]
于是,我自己写了一个加速减速效果(系统自己提供的加速减速效果实在是太不明显了),代码如下:
if (t < 0.4) {
return (float)(t*t);
}else if (t >= 0.4 &&t <= 0.6) {
return (float)(3.4*t - 1.2);
}else
return (float)(1.0f - (1.0f - t) * (1.0f - t));
函数图象如下:
这样加速减速效果就非常明显啦!当然啦,自己去创建一个类似DecelerateInterpolator的类,将这个算法写入getInterpolation()方法就可以啦
同时,我想,旋转等效果的动画算法原理也应该是一样的,所以,咱们可以自己去实现很多效果的动画!