精通Android自定义View(十二)绘制圆形进度条

1 绘图基础简析

1 精通Android自定义View(一)View的绘制流程简述
2 精通Android自定义View(二)View绘制三部曲
3 精通Android自定义View(三)View绘制三部曲综合简述
4 精通Android自定义View(四)自定义属性使用详解
5 精通Android自定义View(五)自定义属性值使用详情


6 精通Android自定义View(六)绘制篇Paint分析
7 精通Android自定义View(七)绘制篇Canvas分析
8 精通Android自定义View(八)绘制篇Canvas分析绘制文字
9 精通Android自定义View(九)绘制篇Canvas分析绘制图片
10 精通Android自定义View(十)绘制篇Canvas分析之绘制Path
11 精通Android自定义View(十一)绘制篇Canvas分析之裁剪


12 精通Android自定义View(十二)绘制圆形进度条

2 效果图

3 源码


public class CustomLineProgressView extends View {

    //设置默认最大进度
    public int max =100;
    //设置默认初始化进度
    public int progress=0;
    //设置View默认的大小
    private int mDefaultWidth = dp2px(60);
    private int mDefaultPadding = dp2px(10);

    // 定义设置进度圆的默认半径
    private int mRadius = mDefaultWidth/2;
    //圆环的默认宽度
    private  int mProgressBarHeight = dp2px(5);
    //声明初始化一个画笔
    private Paint mPaint = new Paint();
    //设置未加载进度的默认颜色
    private int mUnReachedBarColor = 0xffe6e6e6;
    //设置已加载进度的默认颜色
    private int mReachedBarColor = 0xff89cc99;

    //测量后的实际view的大小
    private int mMeasureWidth;
    private int mMeasureHeight;
    private RectF mRectF;


    public CustomLineProgressView(Context context) {
        super(context);
        //初始化画笔风格,图形参数,如圆圈的颜色,绘制的文字等
        initView();
    }
    public CustomLineProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(false);// 防止onDraw方法不执行
        //初始化画笔风格,图形参数,如圆圈的颜色,绘制的文字等
        initView();

        //获取自定义View中自定义属性的值
        TypedArray lTypedArray = context.obtainStyledAttributes(attrs, R.styleable.circularProgress);
        //获取定义圆弧进度的颜色
        mReachedBarColor=lTypedArray.getColor(R.styleable.circularProgress_progressColor,mReachedBarColor);
        mUnReachedBarColor=lTypedArray.getColor(R.styleable.circularProgress_progressBackgroundColor,mUnReachedBarColor);
    }
    private void initView() {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setTextSize(dp2px(10));

    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        Log.e("progress",w + " h " +h+" oldw "+oldw+" oldh "+ oldh);

    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量计算
        mMeasureWidth = measureSize(widthMeasureSpec);
        mMeasureHeight = measureSize(heightMeasureSpec);
        //重新测量
        setMeasuredDimension(mMeasureWidth, mMeasureHeight);
        //绘制圆环的半径
        mRadius=(mMeasureWidth -mDefaultPadding*2-mProgressBarHeight-getPaddingLeft()-getPaddingRight())/2;
        //绘制进度圆弧的外切矩形定义
        mRectF = new RectF(-mRadius, -mRadius, mRadius, mRadius);
        //动态设置绘制文本的大小
        mPaint.setTextSize(dp2px(mRadius/4));

    }
    private int measureSize(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY){
            //当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
            result = specSize;
        }else {
            result = mDefaultWidth;   //指定默认大小
            if (specMode == MeasureSpec.AT_MOST){
                result = Math.min(result,specSize);
            }
        }
        return result;
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {

        //获取显示进度的文字指示
        String text = progress + "%";
         //获取显示进度的文字的宽与高
        float textWidth = mPaint.measureText(text);
        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;
        canvas.save();

        //将画布移动到中心 view中心为原点(0,0)
        canvas.translate(mMeasureWidth/2,mMeasureHeight/2);
        mPaint.setStyle(Paint.Style.STROKE);
        //绘制未加载的进度,也就是绘制环背景
        mPaint.setColor(mUnReachedBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight);
        //点(0,0)为原心
        canvas.drawCircle(0, 0, mRadius, mPaint);

        //绘制已加载的圆环进度
        mPaint.setColor(mReachedBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight);
        //计算进度圆弧角度
        float sweepAngle = progress * 1.0f / max * 360;
        //绘制圆弧进度
        canvas.drawArc(mRectF, 0,
                sweepAngle, false, mPaint);

        //绘制显示进行的颜色
        mPaint.setStyle(Paint.Style.FILL);
        //绘制显示文本
        canvas.drawText(text, - textWidth / 2, - textHeight,
                mPaint);

        canvas.restore();

    }



    //将设置的db转为屏幕像素
    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }


    //设置最大进度
    public void setMax(int i) {
        if (i<0||i>100){
            i=100;
        }
        max=i;
    }

    //更新进度
    public void setProgress(int number) {
        if (number>100){
            number=100;
        }
        if (number<0){
            number=0;
        }
        progress=number;
        invalidate();
    }


    /**
     * 设置进度已加载进度条的颜色
     * 这里只写了这个设置颜色
     * 当然也可以写出代码动态设置改变 未加载进度条的颜色
     * 还有显示文字的颜色
     * 还有进度条的宽度等等
     * @param color
     */
    public void setReachedBarColor(int color){
        this.mReachedBarColor = color;
    }

 

早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页