简单实现领取进度圆环

在这里插入图片描述

/**
 *  领取进度
 * @author 
 * @date 2019-3-5
 *
 * 1先初始化 2setNewColor  3setStaticProgressNum/setDynamicProgressNum 设置进度
 */
public class CircleBarView extends View {

    /**
     * 绘制前景圆弧的画笔
     */
    private Paint progressPaint;
    /**
     * 处理动画变化的过程 进度动画
     */
    private CircleBarAnim anim;
    /**
     * 背景圆弧的画笔
     */
    private Paint bgPaint;
    /**
     * 具体的进度条数值
     */
    private float progressNum;
    /**
     * 进度条最大值
     */
    private float maxNum = 100;
    /**
     * 进度条圆弧扫过的角度
     */
    private float progressSweepAngle;
    /**
     * 进度条圆弧颜色
     */
    private int progressColor;
    /**
     * 背景圆弧颜色
     */
    private int bgColor;
    /**
     * 背景圆弧的起始角度
     */
    private float startAngle;
    /**
     * 背景圆弧扫过的角度
     */
    private float sweepAngle;
    /**
     * 圆弧进度条宽度
     */
    private float barWidth;
    /**
     * 绘制圆弧的矩形区域
     */
    private RectF mRectF;
    /**
     * 自定义View默认的宽高
     */
    private int defaultSize;

    public CircleBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleBarView);
        //默认为绿色
        progressColor = typedArray.getColor(R.styleable.CircleBarView_progress_color, Color.GREEN);
        //默认为灰色
        bgColor = typedArray.getColor(R.styleable.CircleBarView_bg_color, Color.GRAY);

        //默认为0
        startAngle = typedArray.getFloat(R.styleable.CircleBarView_start_angle, 0);
        //默认为360
        sweepAngle = typedArray.getFloat(R.styleable.CircleBarView_sweep_angle, 360);
        //默认为10dp
        barWidth = typedArray.getDimension(R.styleable.CircleBarView_bar_width, SysUtils.dipToPx(context, 10));
        typedArray.recycle();//typedArray用完之后需要回收,防止内存泄漏

        defaultSize = SysUtils.dipToPx(context, 100);

        //进度弧画笔初始化...
        progressPaint = new Paint();
        progressPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
        progressPaint.setAntiAlias(true);//设置抗锯齿
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(barWidth);
        progressPaint.setStrokeCap(Paint.Cap.ROUND);
        //背景弧画笔初始化...
        bgPaint = new Paint();
        bgPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
        bgPaint.setColor(bgColor);
        bgPaint.setStrokeWidth(barWidth);
        bgPaint.setAntiAlias(true);//设置抗锯齿
        bgPaint.setStrokeCap(Paint.Cap.ROUND);

        progressNum = 0;
        progressSweepAngle = 0;

        mRectF = new RectF();

    }
    public void setNewColor(int colorResourceBG,int colorResourceProgress){
        bgPaint.setColor(getResources().getColor(colorResourceBG));
        progressPaint.setColor(getResources().getColor(colorResourceProgress));

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int height = measureSize(defaultSize, heightMeasureSpec);
        int width = measureSize(defaultSize, widthMeasureSpec);
        int min = Math.min(width, height);// 获取View最短边的长度
        setMeasuredDimension(min, min);// 强制改View为以最短边为长度的正方形

        if (min >= barWidth * 2) {//这里简单限制了圆弧的最大宽度
            mRectF.set(barWidth / 2, barWidth / 2, min - barWidth / 2, min - barWidth / 2);
        }

    }

    private int measureSize(int defaultSize, int measureSpec) {
        int result = defaultSize;
        int specMode = View.MeasureSpec.getMode(measureSpec);
        int specSize = View.MeasureSpec.getSize(measureSpec);

        if (specMode == View.MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == View.MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制 背景弧度
        canvas.drawArc(mRectF, startAngle, sweepAngle, false, bgPaint);
        //绘制 进度弧度
        canvas.drawArc(mRectF, startAngle, progressSweepAngle, false, progressPaint);
    }

    /**
     * 无动画进度
     *
     * @param progressNum
     */
    public void setStaticProgressNum(float progressNum) {

        progressSweepAngle = sweepAngle * progressNum / maxNum;
        invalidate();
    }

    /**
     * 动画绘制进度
     *
     * @param progressNum
     * @param time
     */
    public void setDynamicProgressNum(float progressNum, int time) {

        anim = new CircleBarAnim();
        this.progressNum = progressNum;
        anim.setDuration(time);
        this.startAnimation(anim);
    }


    /**
     * applyTransformation 处理动画变化的过程
     */
    public class CircleBarAnim extends Animation {

        CircleBarAnim() {

        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);
            //这里计算进度条的比例
            progressSweepAngle = interpolatedTime * sweepAngle * progressNum / maxNum;
            postInvalidate();
        }
    }
}
发布了134 篇原创文章 · 获赞 197 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/u011733020/article/details/99867937