正如@Gil正确指出的那样,您必须处理自定义Interpolator实现.好消息是你实际上并不需要自己实现所有东西.您可以组合2种不同的插值公式:加速/减速主动画,减速插补器取消.
基本上这就是你要找的东西:
正常加速/减速动画:
在中间的某处取消它时的动画:
这是我的快速插补器实现:
static class MyInterpolator extends AccelerateDecelerateInterpolator {
private float phaseShift = 0f;
private boolean isCancelled = false;
private float lastInput = 0f;
/**
* Maps a value representing the elapsed fraction of an animation to a value that represents
* the interpolated fraction. This interpolated value is then multiplied by the change in
* value of an animation to derive the animated value at the current elapsed animation time.
*
* @param input A value between 0 and 1.0 indicating our current point
* in the animation where 0 represents the start and 1.0 represents
* the end
* @return The interpolation value. This value can be more than 1.0 for
* interpolators which overshoot their targets, or less than 0 for
* interpolators that undershoot their targets.
*/
@Override
public float getInterpolation(float input) {
lastInput = input;
if(!isCancelled)
{
return super.getInterpolation(input);
}
else
{
return getCancellationInterpolation(input) - phaseShift;
}
}
public void cancel()
{
isCancelled = true;
this.phaseShift = getCancellationInterpolation(lastInput) - super.getInterpolation(lastInput);
}
private float getCancellationInterpolation(float input)
{
return (1.0f - (1.0f - input) * (1.0f - input));
}
}
如您所见,我使用默认插值进行普通动画,并在取消动画时切换减速.显然这段代码并不完美(它不会重置phaseShift值和isCancelled标志,如果你使用重复模式会导致错误计算),但这是你希望自己能够找到的东西:)
我创建了示例项目on GitHub,因此您可以看到它的外观
跟进
我用公式玩了一下,并采用了DecelerateInterpolator实现的第二部分.我介绍了因子参数,它可以帮助您控制取消发生的速度(某种牵引力).设定因子为1.5给我这个:
正如你所看到的,当我在~0.5点点击取消时,动画会更快地被取消(因此它不会像前面的例子那样一直到0.7的距离).它给人一种更好的真实感觉.更高的因素 – 动画停止的速度更快.
这是一个更新的插补器:
static class MyInterpolator extends AccelerateDecelerateInterpolator {
......
private float factor = 1.5f;
.......
private float getCancellationInterpolation(float input)
{
if(factor == 1)
{
return (1.0f - (1.0f - input) * (1.0f - input));
}
else
{
return (float)(1.0f - Math.pow((1.0f - input), 2 * factor));
}
}
}