Android环形进度条

一个通俗易懂的环形进度条,可以定制颜色角度,监听进度。

这里写图片描述

定义一个attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleProgressView">
        <!--画笔宽度-->
        <attr name="progress_width" format="dimension" />
        <!--画笔颜色-->
        <attr name="progress_color" format="color" />
        <!--加载进度起始位置-->
        <attr name="location_start" format="enum">
            <enum name="left" value="1" />
            <enum name="top" value="2" />
            <enum name="right" value="3" />
            <enum name="bottom" value="4" />
        </attr>
    </declare-styleable>
</resources>

自定义CircleProgressView

package com.sample.circleprogressview.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.sample.circleprogressview.R;


/**
 * 普通环形进度条
 */
public class CircleProgressView extends View {
    private int mCurrent;//当前进度
    private Paint mBgPaint;//背景弧线paint
    private Paint mProgressPaint;//进度Paint
    private float mProgressWidth;//进度条宽度
    private int mProgressColor = Color.RED;//进度条颜色
    private int locationStart;//起始位置
    private float startAngle;//开始角度
    private ValueAnimator mAnimator;

    public CircleProgressView(Context context) {
        this(context, null);
    }

    public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
        locationStart = typedArray.getInt(R.styleable.CircleProgressView_location_start, 1);
        mProgressWidth = typedArray.getDimension(R.styleable.CircleProgressView_progress_width, dp2px(context, 4));
        mProgressColor = typedArray.getColor(R.styleable.CircleProgressView_progress_color, mProgressColor);
        typedArray.recycle();

        //背景圆弧
        mBgPaint = new Paint();
        mBgPaint.setAntiAlias(true);
        mBgPaint.setStrokeWidth(mProgressWidth);
        mBgPaint.setStyle(Paint.Style.STROKE);
        mBgPaint.setColor(Color.parseColor("#eaecf0"));
        mBgPaint.setStrokeCap(Paint.Cap.ROUND);

        //进度圆弧
        mProgressPaint = new Paint();
        mProgressPaint.setAntiAlias(true);
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setStrokeWidth(mProgressWidth);
        mProgressPaint.setColor(mProgressColor);
        mProgressPaint.setStrokeCap(Paint.Cap.ROUND);

        //进度条起始角度
        if (locationStart == 1) {//左
            startAngle = -180;
        } else if (locationStart == 2) {//上
            startAngle = -90;
        } else if (locationStart == 3) {//右
            startAngle = 0;
        } else if (locationStart == 4) {//下
            startAngle = 90;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int size = width < height ? width : height;
        setMeasuredDimension(size, size);
    }

    /**
     * oval  // 绘制范围
     * startAngle  // 开始角度
     * sweepAngle  // 扫过角度
     * useCenter   // 是否使用中心
     */
    @Override
    protected void onDraw(Canvas canvas) {
        //绘制背景圆弧
        RectF rectF = new RectF(mProgressWidth / 2, mProgressWidth / 2, getWidth() - mProgressWidth / 2, getHeight() - mProgressWidth / 2);
        canvas.drawArc(rectF, 0, 360, false, mBgPaint);

        //绘制当前进度
        float sweepAngle = 360 * mCurrent / 100;
        canvas.drawArc(rectF, startAngle, sweepAngle, false, mProgressPaint);
    }

    public int getCurrent() {
        return mCurrent;
    }

    /**
     * 设置进度
     *
     * @param current
     */
    public void setCurrent(int current) {
        mCurrent = current;
        invalidate();
    }

    private int tCurrent = -1;

    /**
     * 动画效果
     *
     * @param current  精度条进度:0-100
     * @param duration 动画时间
     */
    public void startAnimProgress(int current, int duration) {
        mAnimator = ValueAnimator.ofInt(0, current);
        mAnimator.setDuration(duration);
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int current = (int) animation.getAnimatedValue();
                if (tCurrent != current) {
                    tCurrent = current;
                    setCurrent(current);
                    if (mOnAnimProgressListener != null)
                        mOnAnimProgressListener.valueUpdate(current);
                }
            }
        });
        mAnimator.start();
    }

    public interface OnAnimProgressListener {
        void valueUpdate(int progress);
    }

    private OnAnimProgressListener mOnAnimProgressListener;

    /**
     * 监听进度条进度
     *
     * @param onAnimProgressListener
     */
    public void setOnAnimProgressListener(OnAnimProgressListener onAnimProgressListener) {
        mOnAnimProgressListener = onAnimProgressListener;
    }

    public void destroy() {
        if (mAnimator != null) {
            mAnimator.cancel();
        }
    }

    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

代码就这么些,接下来我们测算一下

package com.sample.circleprogressview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.sample.circleprogressview.widget.CircleProgressView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private CircleProgressView circle_progress;
    private TextView tv_progress;
    private Button btn_start;
    private Button btn_reset;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn_start = (Button) findViewById(R.id.btn_start);
        btn_reset = (Button) findViewById(R.id.btn_reset);
        circle_progress = (CircleProgressView) findViewById(R.id.circle_progress);
        tv_progress = (TextView) findViewById(R.id.tv_progress);

        btn_start.setOnClickListener(this);
        btn_reset.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                //开锁执行动画效果
                circle_progress.startAnimProgress(50, 1200);
                //监听进度条进度
                circle_progress.setOnAnimProgressListener(new CircleProgressView.OnAnimProgressListener() {
                    @Override
                    public void valueUpdate(int progress) {
                        tv_progress.setText(String.valueOf(progress));
                    }
                });
                break;
            case R.id.btn_reset:
                circle_progress.setCurrent(0);
                tv_progress.setText("0");
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (circle_progress != null) {
            circle_progress.destroy();
        }
    }
}

代码下载

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/80927243