Interpolator就是我们平时说的插值器。插值器什么意思呢?看到这三个字还真是不太好理解它到底干嘛用的。其实它就是控制动画的变化速率的。怎么控制?根据动画的时间完成度计算动画完成度。还是不懂?比如:我们一张图片沿Y正方向平移1200像素,时间是2000毫秒。如果是匀速平移,时间在1000秒的时候时间完成度是0.5,动画完成度也是0.5,那么位移应该是0.5*1200=600像素。这个时候图片应该平移到Y=600的地方。匀速的动画完成度随时间的变化如下图:
Interpolator是一个接口,继承了TimeInterpolator。只有一个未实现方法:getInterpolation(float input)。系统为我们提供了很多Interpolator的实现类,匀速只是其中一种,还有先加上再减速,一直加速等等很多。我们依次实现这些效果:
动画中依次实现了系统提供的种种Interpolator实现类,如下:
其中先加速再减速是系统默认的变化速率。就是如果我们不设置这个值的时候,就是先加速再减速的效果。我们看看最简单的匀速LinearInterpolator累的实现,而且我们只需要关注getInterpolation(float input)方法的实现:
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
}
}
这个方法输出的就是我们的动画完成度,而输入的就是时间完成度。时间都是匀速走的,一秒一秒,我们无法让它加速或者减速。可以看出,匀速的实现很简单,直接返回输入参数。这是因为匀速的时候动画完成度和时间完成度是一样的。我们再看看默认的先加速再加速类:AccelerateDecelerateInterpolator
public class AccelerateDecelerateInterpolator extends BaseInterpolator
implements NativeInterpolatorFactory {
public AccelerateDecelerateInterpolator() {
}
@SuppressWarnings({"UnusedDeclaration"})
public AccelerateDecelerateInterpolator(Context context,AttributeSet attrs) {
}
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
}
}
拿到时间完成度后,进行了一系列的运算,通过这个算法得到动画完成度。我们看一下它的曲线图:
从图片可以看出,动画的完成度的变化速率是先增大再变小。知道了插值器是什么以及怎么实现的之后,我们就可以实现自己的插值器了,让动画的变化速率按照我们的意愿来。我们先画出动画完成度随时间完成度的变化曲线:
简单手画了下,变化也很简单,数学好的可以做复杂的变化。。。然后我们定义一个类FirstInterpolator:
public class FirstInterpolator implements Interpolator {
@Override
public float getInterpolation(float input) {
float f ;
if (input < 0.25) {
f = input *2;
}else if (input < 0.5) {
f = input*2 - 0.5f;
}else if (input < 0.75){
f = 0.5f;
}else {
f = input * 2 - 1;
}
return f;
}
}
从曲线图可以看出,在时间完成度为0到0.25的时候,匀速变化,0.25到0.5的时候,回到出发点再匀速变化,0.5到0.75的时候是停止变化,0.75到1的时候接着匀速变化。效果如下:
可以看到,动画是按照我们设计的变化速率变化的。从这里就可以看出,Interpolator对于我们实现一些比较精致的效果是非常有帮助的,我们可以借助系统实现了的Interpolator类,也可以按照自己的意愿实现自己的Interpolator,它的作用不仅于此,也和我们后面要说的估值器有很紧密的关系。