Android 自定义圆形进度条

说在前面的话,利用点空余时间,把以前的都写一遍,毕竟,基础不能忘记。现在已经有了很多*可以用,但是基础就是让你怎么更好的使用*。好了,不多说。

直接上代码,注释都有的。

贴个效果图先:

Android 自定义圆形进度条


接下来就是代码了:


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.example.myapplication.R;

/**
 * Created by Avater on 2017/12/7.
 */

public class AvaterProgressCycle extends View {

    private int mFirstColor = Color.parseColor("#191970");//圆形进度的背景色
    private int mSecondColor = Color.parseColor("#006400");//进度的背景颜色
    private int mWidth = 40;//圆环的宽度
    private int mTextSize = 40;//字体的大小
    private int mTextColor = mFirstColor;//字体的颜色
    private Paint mPaint = new Paint();//画笔
    private float currentvalue;//当前的弧度值(0-360)
    private int mGoal;//设置的进度目标

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

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

    public AvaterProgressCycle(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint.setAntiAlias(true);//画笔设置抗锯齿,否则圆形边缘会锐化,变丑
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AvaterProgressCycle);//获取自定义属性的集合
        int size = array.getIndexCount();
        for (int i = 0; i < size; i++) {//遍历取出对应的值
            int attr = array.getIndex(i);
            switch (attr) {
                case R.styleable.AvaterProgressCycle_FirstColor:
                    mFirstColor = array.getColor(attr, Color.parseColor("#191970"));
                    break;
                case R.styleable.AvaterProgressCycle_SecondColor:
                    mSecondColor = array.getColor(attr, Color.parseColor("#006400"));
                    break;
                case R.styleable.AvaterProgressCycle_TextColor:
                    mTextColor = array.getColor(attr, mFirstColor);
                    break;
                case R.styleable.AvaterProgressCycle_CircleWidth:
                    mWidth = array.getInteger(attr, 40);
                    break;
                case R.styleable.AvaterProgressCycle_TextSize:
                    mTextSize = (int) array.getDimension(attr, 30);
                    break;
            }
        }
        array.recycle();//及时回收
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 1画圆
         * 2画弧度
         * 3画文字
         */
        CanvasCircle(canvas);
        CanvasArc(canvas);
        CanvasText(canvas);
    }

    /**
     * 画文字
     *
     * @param canvas
     */
    private void CanvasText(Canvas canvas) {
        mPaint.setColor(mTextColor);//设置文字的颜色
        mPaint.setStyle(Paint.Style.FILL);//设置为实心
        mPaint.setTextSize(mTextSize);//设置文字的大小
        float progress = (currentvalue / 360);//当前的进度,需要转化处理
        String result = String.format("%.2f", progress);//保留两位小数
        int v = (int) (Float.parseFloat(result) * 100);//取整
        String mess = v + "%";//拼揍
        Rect rect = new Rect();//边距
        mPaint.getTextBounds(mess, 0, mess.length(), rect);//获取文字的边距
        int width = rect.width();//文字的宽度
        int height = rect.height();//文字的高度
        int dx = getMeasuredWidth() / 2 - width / 2;//文字的中心坐标
        int dy = getMeasuredHeight() / 2 + height / 2;//文字的中心坐标
        canvas.drawText(mess, dx, dy, mPaint);
    }

    /**
     * 画弧度
     *
     * @param canvas
     */
    private void CanvasArc(Canvas canvas) {
        mPaint.setColor(mSecondColor);//设置圆弧的进度颜色
        float left = mWidth;//距离左边的距离
        float top = mWidth;//距离上面的距离
        float right = getMeasuredWidth() - mWidth;//距离右边的距离
        float bottom = getMeasuredWidth() - mWidth;//距离下边的距离
        RectF oval = new RectF(left, top, right, bottom);
        canvas.drawArc(oval, -90, currentvalue, false, mPaint);//false : 不画扇形弧边,只画弧长
    }

    /**
     * 画圆
     *
     * @param canvas
     */
    private void CanvasCircle(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE);//设置空心
        mPaint.setColor(mFirstColor);//设置画笔的颜色
        mPaint.setStrokeWidth(mWidth);//设置画笔的宽度
        int dx = getMeasuredWidth() / 2;//圆心x轴的点
        int dy = getMeasuredHeight() / 2;//圆心y轴的点
        int radius = getMeasuredWidth() / 2 - mWidth; //该圆的半径 = 该View 的宽度 - 圆环的宽度
        canvas.drawCircle(dx, dy, radius, mPaint);
    }

    /**
     * @param progress 1-360  设置的时候,自己根据需求来转换
     */
    public void setProgress(final int progress) {
        this.mGoal = progress;
        mHandler.sendEmptyMessageDelayed(1, 10);//发送延迟的消息
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                currentvalue++;//变量自增
                postInvalidate();//通知绘图
                if (currentvalue == mGoal) {//条件判断
                    return;
                }
                mHandler.sendEmptyMessageDelayed(1, 10);
            }
        }
    };

}