上篇文章写的加载动画感觉不太对,于是重新写了一个控件。效果如下:
采用ValueAnimator来实现动画
1.先创建继承ViewGroup的类,在初始化时添加三个ImageView
private void init(Context context){
ImageView leftImg = new ImageView(context);
leftImg.setBackground(getResources().getDrawable(R.drawable.leftcircle));
addView(leftImg);
ImageView centerImg = new ImageView(context);
centerImg.setBackground(getResources().getDrawable(R.drawable.centercircle));
addView(centerImg);
ImageView rightImg = new ImageView(context);
rightImg.setBackground(getResources().getDrawable(R.drawable.rightcircle));
addView(rightImg);
}
2.在onLayout中设置三个圆的位置,初始位置都在正中心,left的圆向左边运动,right的圆向右边运动,中间保持不动
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
View left = getChildAt(0);
left.layout(width / 2 - height / 2 - nowH, 0, width / 2 + height / 2 - nowH, height);
View center = getChildAt(1);
center.layout(width / 2 - height / 2, 0, width / 2 + height / 2, height);
View right = getChildAt(2);
right.layout(width / 2 - height / 2 + nowH, 0, width / 2 + height / 2 + nowH, height);
}
3.重写Evaluator,这里将运动的圆看作在与屏幕垂直的方向上画圆,从屏幕上看就在左右运动。
public class ParabolicEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int r = width / 2 - height / 2;//圆半径
double v0 = Math.PI * r * 2;//匀速速度
double c = v0 * fraction;//圆弧长
double a = (c / r);//弧度
int h = (int)(r * Math.sin(a));
if((fraction >= 0.5 && beforeTime <= 0.5) || (beforeTime > 0.9 && fraction > 0)){
View left = getChildAt(0);
View center = getChildAt(1);
View right = getChildAt(2);
Drawable leftD = left.getBackground();
Drawable centerD = center.getBackground();
Drawable rightD = right.getBackground();
left.setBackground(centerD);
center.setBackground(rightD);
right.setBackground(leftD);
}
beforeTime = fraction;
return h;
}
}
4.初始化ValueAnimator,这里要设置插值器为线性插值器(默认的插值器是加减速插值器)
public void startAnim(){
ValueAnimator valueAnimator = ValueAnimator.ofObject(new ParabolicEvaluator(), 0, 0);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
nowH = (Integer) animation.getAnimatedValue();
requestLayout();
}
});
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(time);
valueAnimator.setRepeatCount(Animation.INFINITE);
valueAnimator.start();
}
完成。