Android自定义圆形进度条

先看一下效果
效果预览

1.定义自定义View属性

在res/values/目录下新建attrs.xml,内容如下

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="CircleProgress">
        <!--进度条颜色-->
        <attr name="progressColor" format="color"/>
        <!--进度条轨道颜色-->
        <attr name="orbitColor" format="color"/>
        <!--进度显示文本颜色-->
        <attr name="textColor" format="color"/>
        <!--进度条轨道宽度-->
        <attr name="orbitWidth" format="dimension"/>
        <!--进度显示文本字体大小-->
        <attr name="textSize" format="dimension"/>
        <!--是否显示进度文本-->
        <attr name="enableText" format="boolean"/>
        <attr name="maxProgress" format="integer"/>
        <attr name="progress" format="integer"/>

    </declare-styleable>

</resources>

2.新建CircleProgress类

public class CircleProgress extends View {

    private final static String TAG = "CircleProgress";

    private int mHeight;
    private int mWidth;
    private int mOrbitWidth;
    private int mTextSize;
    private boolean mEnableText;
    private int mColorProgress;
    private int mColorOrbit;
    private int mColorText;
    private int mMaxProgress;
    private int mProgress;
    private Paint mPaint;
    private int mRadius;

    public int getOrbitWidth() {
        return mOrbitWidth;
    }

    public void setOrbitWidth(int orbitWidth) {
        mOrbitWidth = orbitWidth;
    }

    public int getTextSize() {
        return mTextSize;
    }

    public void setTextSize(int textSize) {
        mTextSize = textSize;
    }

    public boolean isEnableText() {
        return mEnableText;
    }

    public void setEnableText(boolean enableText) {
        mEnableText = enableText;
    }

    public int getColorProgress() {
        return mColorProgress;
    }

    public void setColorProgress(int colorProgress) {
        mColorProgress = colorProgress;
    }

    public int getColorOrbit() {
        return mColorOrbit;
    }

    public void setColorOrbit(int colorOrbit) {
        mColorOrbit = colorOrbit;
    }

    public int getColorText() {
        return mColorText;
    }

    public void setColorText(int colorText) {
        mColorText = colorText;
    }

    public int getMaxProgress() {
        return mMaxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        mMaxProgress = maxProgress;
    }

    public int getProgress() {
        return mProgress;
    }

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

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

    public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleProgress, defStyleAttr, 0);
        mOrbitWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgress_orbitWidth, DimenUtil.dp2px(context, 2f));
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgress_textSize, DimenUtil.sp2px(context, 12f));
        mEnableText = typedArray.getBoolean(R.styleable.CircleProgress_enableText, true);
        int colorAccent = ContextCompat.getColor(context, R.color.colorAccent);
        int defaultOrbitColor = ContextCompat.getColor(context,R.color.cardview_light_background);
        mColorProgress = typedArray.getColor(R.styleable.CircleProgress_progressColor, colorAccent);
        mColorOrbit = typedArray.getColor(R.styleable.CircleProgress_orbitColor, defaultOrbitColor);
        mColorText = typedArray.getColor(R.styleable.CircleProgress_textColor, colorAccent);
        mMaxProgress = typedArray.getInt(R.styleable.CircleProgress_maxProgress, 100);
        mProgress = typedArray.getInt(R.styleable.CircleProgress_progress, 0);
        typedArray.recycle();

        mPaint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mWidth>mHeight){
            mRadius = mHeight/2-mOrbitWidth;
        }else {
            mRadius = mWidth/2-mOrbitWidth;
        }
        int cx = getWidth()/2;
        int cy = getHeight()/2;

        //画进度条轨道
        mPaint.setColor(mColorOrbit); //设置圆的颜色
        mPaint.setStyle(STROKE); //设置空心
        mPaint.setStrokeWidth(mOrbitWidth); //设置圆的宽度
        mPaint.setAntiAlias(true);  //消除锯齿
        canvas.drawCircle(cx, cy, mRadius, mPaint); //画出圆

        //画进度(圆弧)
        mPaint.setColor(mColorProgress);  //设置进度的颜色
        RectF oval = new RectF(cx-mRadius,cy-mRadius,cx+mRadius,cy+mRadius);
        canvas.drawArc(oval, -90, 360 * (mProgress*1f / mMaxProgress), false, mPaint);  //根据进度画圆弧

        //画圆环内百分比文字
        if (mEnableText) {
            Rect rect = new Rect();
            mPaint.setColor(mColorText);
            mPaint.setTextSize(mTextSize);
            mPaint.setStrokeWidth(0);
            String progressText = getProgressText();
            mPaint.getTextBounds(progressText, 0, progressText.length(), rect);
            Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
            int baseline = (mHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
            canvas.drawText(progressText, mHeight / 2 - rect.width() / 2, baseline, mPaint);
        }
    }

    public void setProgress(int progress){
        mProgress = progress;
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mHeight = getMeasuredHeight();
        mWidth = getMeasuredWidth();

    }

    public String getProgressText() {
        return (int)(100*(mProgress * 1f / mMaxProgress) )+ "%";
    }
}

3.使用方法

<CircleProgress
    app:orbitColor="@color/colorGray3"
    app:textColor="@color/colorWhite"
    app:textSize="13sp"
    android:layout_gravity="center_horizontal"
    android:layout_width="40dp"
    android:layout_height="40dp"/>

猜你喜欢

转载自blog.csdn.net/bobcat_kay/article/details/80101278