自定义进度条(2)

这个进度条是一个月前写的,现在挖出来。

这是一个类似仪表盘的原型进度条:


如果进度大于零,它就会从弧外部左下角开始增长(不与这个弧重叠,这个弧是基线),会有一个动画。

这里涉及到画圆的知识,还有动画。动画的实现我市直接在onDraw中进行更改再调用invalidate()实现的。


好,首先是各种变量:

    /**
     * 进度条基线颜色与进度条颜色
     */
    private int baseArcColor = 0xff69b6e4, progressColor = 0xffffda2c;

    /**
     * 进度条基线宽度与进度条宽度(px)
     */
    private int baseArcWidth = 2, progressWidth = 10;

    /**
     * 进度条基线画笔与进度条画笔
     */
    private Paint baseArcPaint, progressPaint;

    /**
     * 进度条进度(min = 0, max = 100)
     */
    private float progress = 0;

    /**
     * 绘制起始位置(>90)系统默认的起始位置是x轴正方向
     * 改变位置时以顺时针方向相加相应的度数
     */
    private int startDegree = 145;

    /**
     * 执行动画使用的当前进度与总共前进的进度
     */
    private float currentProgress = 0, sweepProgress = 0;
    private float totalSweepProgress = 0;

    /**
     * 绘图区域
     */
    private RectF area, innerArea;

area是总绘图区域,innerArea是用来话里面进度条的基线


初始化方法:

    private void initView() {
        baseArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        baseArcPaint.setStyle(Paint.Style.STROKE);
        baseArcPaint.setColor(baseArcColor);
        baseArcPaint.setStrokeWidth(baseArcWidth);

        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        progressPaint.setStyle(Paint.Style.STROKE);
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(progressWidth);
        progressPaint.setStrokeCap(Paint.Cap.ROUND);

        totalSweepProgress = 360 - (startDegree - 90) * 2;
        setProgress(0);
    }
setProgress()方法:

    public void setProgress(float progress) {
        this.progress = progress;
        sweepProgress = progress / 100 * totalSweepProgress;
        invalidate();
    }


其次,onMeasure,我们设置它是是一个自适应的正方形:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);


        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.EXACTLY) {
            height = width;
        } else if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.AT_MOST) {
            height = width;
        } else {
            if (height == 0) height = width;
            if (width == 0) width = height;
            if (height > width) {
                height = width;
            } else {
                width = height;
            }
        }
        setMeasuredDimension(width, height);
    }

在onSizeChange中控制绘图区域:

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        area = new RectF(0, 0, w - progressWidth, h - progressWidth);
        area.offset(progressWidth / 2, progressWidth / 2);

        innerArea = new RectF(0, 0, w - progressWidth * 3 / 2, h - progressWidth * 3 / 2);
        innerArea.offset(progressWidth * 3 / 4, progressWidth * 3 / 4);
    }

在onDraw中绘制:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制基线
        canvas.drawArc(innerArea, startDegree, totalSweepProgress, false, baseArcPaint);

        //绘制进度
        if (progress > 0) {
            currentProgress += 2;
            if (currentProgress > totalSweepProgress) currentProgress = totalSweepProgress;
            canvas.drawArc(area, startDegree, currentProgress, false, progressPaint);
            if (currentProgress < sweepProgress) {
                invalidate();
                //postInvalidateDelayed(10);
            }
        }
    }

构造方法记得加上,这样就完成了,完成后可以自己看下实现的效果^.^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值