Android 兩個小球轉動的進度條

public class CircleProgressBar extends View {

    private Paint mFirstPaint;
    private Paint mSecondPaint;

    private Context mContext;
    private CircleInfo mFirstCircle;
    private CircleInfo mSecondCircle;
    private float mCenterX;
    private float mCenterY;
    private float mDistance = 50;

    private static final float MAX_RADIUS = 60;
    private static final float MIN_RADIUS = 15;

    public CircleProgressBar(Context context) {
        super(context);
        init(context);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context){
        mContext = context;
        initPaint();
        initCircle();
        startProgressBarAnimator();
    }

    private void initPaint(){
        mFirstPaint = new Paint();
        mFirstPaint.setColor(Color.RED);
        mFirstPaint.setStyle(Paint.Style.FILL);
        mFirstPaint.setAntiAlias(true);

        mSecondPaint = new Paint();
        mSecondPaint.setColor(Color.BLUE);
        mSecondPaint.setStyle(Paint.Style.FILL);
        mSecondPaint.setAntiAlias(true);
    }

    private void initCircle(){
        mFirstCircle = new CircleInfo();
        mFirstCircle.setColor(Color.RED);

        mSecondCircle = new CircleInfo();
        mSecondCircle.setColor(Color.BLUE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2;
        mCenterY = h / 2;

        mFirstCircle.setCenter(mCenterX);
        mSecondCircle.setCenter(mCenterX);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mFirstCircle.getRadius() > mSecondCircle.getRadius()) {
            canvas.drawCircle(mSecondCircle.getCenter(), mCenterY, mSecondCircle.getRadius(), mSecondPaint);
            canvas.drawCircle(mFirstCircle.getCenter(), mCenterY, mFirstCircle.getRadius(), mFirstPaint);
        } else {
            canvas.drawCircle(mFirstCircle.getCenter(), mCenterY, mFirstCircle.getRadius(), mFirstPaint);
            canvas.drawCircle(mSecondCircle.getCenter(), mCenterY, mSecondCircle.getRadius(), mSecondPaint);
        }

    }

    private void startProgressBarAnimator(){
        ValueAnimator firstCenterXAnimation = ValueAnimator.ofFloat(-1, 0, 1, 0, -1);
        firstCenterXAnimation.setRepeatCount(ValueAnimator.INFINITE);
        firstCenterXAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float)animation.getAnimatedValue();
                float centerX = mCenterX + mDistance * value;
                mFirstCircle.setCenter(centerX);
                invalidate();
            }
        });

        ValueAnimator secondCenterXAnimation = ValueAnimator.ofFloat(1, 0, -1, 0, 1);
        secondCenterXAnimation.setRepeatCount(ValueAnimator.INFINITE);
        secondCenterXAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float)animation.getAnimatedValue();
                float centerX = mCenterX + mDistance * value;
                mSecondCircle.setCenter(centerX);
                invalidate();
            }
        });


        float middleRadius = (MAX_RADIUS + MIN_RADIUS) / 2;
        ValueAnimator firstRadiusAnimation = ValueAnimator.ofFloat(middleRadius, MAX_RADIUS, middleRadius, MIN_RADIUS, middleRadius);
        firstRadiusAnimation.setRepeatCount(ValueAnimator.INFINITE);
        firstRadiusAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float)animation.getAnimatedValue();
                mFirstCircle.setRadius(value);
            }
        });

        ValueAnimator secondRadiusAnimation = ValueAnimator.ofFloat(middleRadius, MIN_RADIUS, middleRadius, MAX_RADIUS, middleRadius);
        secondRadiusAnimation.setRepeatCount(ValueAnimator.INFINITE);
        secondRadiusAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float)animation.getAnimatedValue();
                mSecondCircle.setRadius(value);
            }
        });


        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(1500);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorSet.playTogether(firstCenterXAnimation, secondCenterXAnimation, firstRadiusAnimation, secondRadiusAnimation);
        animatorSet.start();
    }
}

CircleInfo

public class CircleInfo {
    private float mCenter;
    private float mRadius;
    private int mColor;

    public void setCenter(float center){
        mCenter = center;
    }
    public float getCenter(){
        return mCenter;
    }

    public void setRadius(float radius){
        mRadius = radius;
    }
    public float getRadius(){
        return mRadius;
    }

    public void setColor(int color){
        mColor = color;
    }
    public int getColor(){
        return mColor;
    }

}

佈局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.cxh.circleprogressbar.MainActivity">

    <com.cxh.circleprogressbar.CircleProgressBar
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>
發佈了109 篇原創文章 · 獲贊 37 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章