实现自由落体并反弹回原来位置, 实现如下.
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "TranslationY", 0, dip2px(getApplicationContext(),200));
animator.setDuration(1000);
animator.setInterpolator(new MyInterpolator());
animator.start();
其核心为自定义的InterPolator 来描述其移动时候的具体位置.
/**
* Created by br on 2015/3/27.
*自由落体反弹,忽略阻力
* @author luo
*/
public class MyInterpolator implements TimeInterpolator {
private static final String TAG = MyInterpolator.class.getSimpleName();
@Override
public float getInterpolation(float input) {
float v;
if (input <= .5) {
v = input * input * 4f;
} else
v = (1-input)*(1-input)*4;
Log.d(TAG, "input ="+input+" v = " + v);
return v;
}
// float v;
// if (input <= .5) {
// v = input * input * 2f;
// } else
// v = .5f+ 2f * (input-.5f) - (input-.5f) * (input-.5f) * 2;
// Log.d(TAG, "input ="+input+" v = " + v);
}
TimeInterpolator 差值器, 函数
getInterpolation()中的参数是[0,1]
若不自定义Interpolator 系统默认为
LinearInterpolator, 其实现如下:
public class LinearInterpolator implements Interpolator, NativeInterpolatorFactory {
//....
public float getInterpolation(float input) {
return input;
}
//...
}
结合上述示例, 从0 移动至200, 其对应[0,1], 若为线性插值器, 当input=0时, 位置为0, 当input=.5时, 位置为100, 当input=1时, 位置为200,
其简单可以理解为[0, 1] 对应[0,200] 的一个映射关系
而我们需要的是在[0,1] 这个过程中, 实现从0 -> 200 -> 0, 那么在input=.5 的时候其位置就应该到达了200, 而input=1时, 其位置应该是0.
显然,,我们可以通过返回的input 来操作器具体的位置.
input在[0, .5] 的过程中我们让其实现[0, 1]的整个过程, 即位置从0 -> 200
input在[.5, 1] 的过程我们让它倒过来[1, 0]实现返回的位移动画, 200 -> 0
简单的实现:
public float getInterpolation(float input) {
float v;
if(input<.5){
v = input*2f;
} else {
v = (1-input)*2;
}
return v;
}
但由于需要模拟重力加速度效果, 终于, 高中学的物理总算是有点用处了.
由于在[0, .5]我们需要实现[0, 1], 那么
S=1/2*a*t^2 可知在时间[0,.5]的时间内,需要从0跑到1 所需的加速度为:
1 = 1/2*a*.5*.5 -> a = 4
因此在<.5时返回的值为
1/2*4*t*t , 当t=.5的时候, 刚好为1, 也就是位置200所对应的值
而当>.5之后,是一个匀减速运动,那么恰好反过来
(1-t)*(1-t)*4;