xml
<com.jianshu.LoadCircleView
android:id="@+id/circle"
android:layout_width="wrap_content"
android:layout_height="100dp"
app:circle_radius="10"
app:duration="800" />
colors.xml
<color name="color_red">#EA4346</color>
<color name="color_black">#646363</color>
<color name="color_blue">#3789F9</color>
attrs.xml
<declare-styleable name="LoadCircleView">
<!--圓的半徑-->
<attr name="circle_radius" format="float" />
<!--持續(xù)時(shí)間-->
<attr name="duration" format="integer" />
</declare-styleable>
自定義view:
public class LoadCircleView extends View {
/**
* 第一個(gè)動(dòng)畫的索引
*/
private int changeIndex = 0;
/**
* 圓的顏色值
*/
private int[] colors = new int[]{
getResources().getColor(R.color.color_red),
getResources().getColor(R.color.color_blue),
getResources().getColor(R.color.color_black)};
/**
* 偏移量
*/
private Float maxWidth = 50f;
/**
* 圓的半徑 默認(rèn)10f
*/
private Float circleRadius = 10f;
/**
* 當(dāng)前偏移的X坐標(biāo)
*/
private Float currentX = 0f;
/**
* 畫筆
*/
private Paint paint;
/**
* 屬性動(dòng)畫
*/
private ValueAnimator valueAnimator;
/**
* 持續(xù)時(shí)間
*/
private int duration = 800;
public LoadCircleView(Context context) {
this(context, null);
}
public LoadCircleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
if (null != attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadCircleView);
circleRadius = typedArray.getFloat(R.styleable.LoadCircleView_circle_radius, circleRadius);
duration = typedArray.getInt(R.styleable.LoadCircleView_duration, duration);
typedArray.recycle();//記得回收
}
startAnimator();
}
/**
* 位移動(dòng)畫
*/
private void startAnimator() {
valueAnimator = ValueAnimator.ofFloat(0f, maxWidth, 0);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentX = (Float) animation.getAnimatedValue();
invalidate();//執(zhí)行刷新onDraw()
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
changePoint(changeIndex);
}
});
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setRepeatCount(-1);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.setDuration(duration);
valueAnimator.start();
}
/**
* 先執(zhí)行動(dòng)畫的目標(biāo)和中間停止的動(dòng)畫目標(biāo)交換
* (顏色切換)
*
* @param index 最先執(zhí)行的動(dòng)畫的索引
*/
private void changePoint(int index) {
int temp = colors[2];
colors[2] = colors[index];
colors[index] = temp;
changeIndex = (index == 0) ? 1 : 0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
/**左邊圓**/
paint.setColor(colors[0]);
canvas.drawCircle(centerX - currentX, centerY, circleRadius, paint);
/**右邊圓**/
paint.setColor(colors[1]);
canvas.drawCircle(centerX + currentX, centerY, circleRadius, paint);
/**中間圓**/
paint.setColor(colors[2]);
canvas.drawCircle(centerX, centerY, circleRadius, paint);
}
//銷毀View的時(shí)候回調(diào)
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
valueAnimator.cancel();
}
}