最終效果,這個動畫是在花瓣上看到的,主要是實現動畫, 程式碼還有優化的地方懶得做了。什麼時候用到這個再來封裝下。
/**
* 一個簡單的載入動畫
*/
public class LoadingView extends View {
/**
* 三個外圈圓的背景色
*/
private int leftCircleColor = Color.parseColor("#e83939");
private int centerColor = Color.parseColor("#70c7d4");
private int rightColor = Color.parseColor("#FF4081");
/**
* 控制元件寬高
*/
private int mWidth;
private int mHeight;
/**
* 三個外圈圓的半徑和padding
*/
private int circleRadius;
private int circlePadding;
/**
* 左右圓動畫的最大和最小半徑
*/
private int leftAndRightMaxRadius;
private int leftAndRightMinRadius;
private int leftInsideRadius;
private int rightInsideRadius;
/**
* 中心圓動畫的最大半徑
*/
private int centerMaxRadius;
private int centerMinRadius;
private int centerInsideRadius;
/**
* 值動畫是否正在播放
*/
private boolean animPlaying;
public LoadingView(Context context) {
super(context);
init(null);
}
public LoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
circleRadius = dip2px(15);
circlePadding = dip2px(50);
leftAndRightMaxRadius = dip2px(9);
leftAndRightMinRadius = dip2px(3);
centerMaxRadius = dip2px(12);
centerMinRadius = dip2px(6);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mWidth == 0 || mHeight == 0)
return;
//畫左邊外圈
Paint leftOutSideCircle = new Paint();
leftOutSideCircle.setColor(leftCircleColor);
leftOutSideCircle.setAntiAlias(true);
canvas.drawCircle(mWidth / 2 - circlePadding, mHeight / 2, circleRadius, leftOutSideCircle);
//畫中心外圈圓
Paint centerOutSidePaint = new Paint();
centerOutSidePaint.setAntiAlias(true);
centerOutSidePaint.setColor(centerColor);
canvas.drawCircle(mWidth / 2, mHeight / 2, circleRadius, centerOutSidePaint);
//畫右邊外圈圓
Paint rightOutSidePaint = new Paint();
rightOutSidePaint.setColor(rightColor);
rightOutSidePaint.setAntiAlias(true);
canvas.drawCircle(mWidth / 2 + circlePadding, mHeight / 2, circleRadius, rightOutSidePaint);
//值動畫播放完成繼續開始重新播放
if (!animPlaying) {
startAnim();
animPlaying = true;
}
//左邊中心圓
Paint leftInSideCircle = new Paint();
leftInSideCircle.setColor(Color.WHITE);
leftInSideCircle.setAntiAlias(true);
canvas.drawCircle(mWidth / 2 - circlePadding, mHeight / 2, leftInsideRadius, leftInSideCircle);
//中間中心圓
Paint centerInSidePaint = new Paint();
centerInSidePaint.setAntiAlias(true);
centerInSidePaint.setColor(Color.WHITE);
canvas.drawCircle(mWidth / 2, mHeight / 2, centerInsideRadius, centerInSidePaint);
//右邊中心圓
Paint rightInSidePaint = new Paint();
rightInSidePaint.setColor(Color.WHITE);
rightInSidePaint.setAntiAlias(true);
canvas.drawCircle(mWidth / 2 + circlePadding, mHeight / 2, rightInsideRadius, rightInSidePaint);
}
private void startAnim() {
final ValueAnimator mValueAnim = ValueAnimator.ofInt(1);
mValueAnim.setInterpolator(new LinearInterpolator());
mValueAnim.setDuration(800);
mValueAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
int tempA = centerMinRadius;
centerMinRadius = centerMaxRadius;
centerMaxRadius = tempA;
int tempB = leftAndRightMaxRadius;
leftAndRightMaxRadius = leftAndRightMinRadius;
leftAndRightMinRadius = tempB;
animPlaying = false;
invalidate();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
mValueAnim.setRepeatMode(ValueAnimator.RESTART);
mValueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float fraction = mValueAnim.getAnimatedFraction();
centerInsideRadius = evaluate(fraction, centerMaxRadius, centerMinRadius);
leftInsideRadius = evaluate(fraction, leftAndRightMinRadius, leftAndRightMaxRadius);
rightInsideRadius = evaluate(fraction, leftAndRightMaxRadius, leftAndRightMinRadius);
Log.i("===TAG===", "centerInsideRadius-" + centerInsideRadius + "leftInsideRadius-" + leftInsideRadius + "rightInsideRadius-" + rightInsideRadius);
invalidate();
}
});
mValueAnim.start();
}
public int evaluate(float fraction, int startValue, int endValue) {
return (int) (startValue + fraction * (endValue - startValue));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
public int dip2px(float dpValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
複製程式碼