上篇文章写的加载动画感觉不太对,于是重新写了一个控件。效果如下:
采用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(); }
完成。