Android带有圆点和下标的进度条|8月更文挑战

993 阅读2分钟

背景

聊天时一朋友问了一个效果怎么实现,于是有了这个文章

效果

先上效果图

Kapture 2021-08-01 at 19.23.39.gif

实现步骤

看到需求后首先想到的是网上应该有现成的轮子,但是搜了搜感觉都不太符合要求,只能手撸了 首先是想直接硬怼,从view开始写,但是看效果,有点小题大做了,然后就直接继承ProgressBar开始装饰.

1.获取控件的宽高

@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //获取控件宽高
    width = MeasureSpec.getSize(widthMeasureSpec);
    height = MeasureSpec.getSize(heightMeasureSpec);
    //PS:如果使用onMeasure获取控件宽高就必须手动调用setMeasuredDimension方法设置宽高否则会报错
    setMeasuredDimension(width, height);
}

2.画下标进度和圆点

由于需求是固定的,4个点和5个下标,为了快速实现采取了最low的代码,直接写死//手动狗头

image.png 效果确实实现了,但是影响后续的扩展,决定优化一波 首先找到的规律是下标总是根据需要进行等分操作,那么位置文字的位置就可以是x轴(宽度 / 等分数 * 当前第几段),y轴 为(控件高度 / 2 + 文字高度)

第一版代码如下

image.png 文字确实显示了, 但是由于下标有开始和结尾,而且算法上没有去考虑到文字的画的方式,导致了开始和结尾的文字显示不全,知道了问题,就开始着手优化

第二版代码如下

//由于有开头和结尾,所以是<=
for (int i = 0; i <= average; i++) {
    //开头需要从起点开始画
    if (i == 0) {
        canvas.drawText(0 + "%", 0 + paintWave.getTextSize() / 2, height / 2 + paintWave.getTextSize() * 3, paintWave);
    } else if (i == average) {
        //结尾为了防止画出去,所以是减去整个文字宽度的3倍
        canvas.drawText(100 / average * i + "%", width / average * i - paintWave.getTextSize() * 3, (height >> 1) + paintWave.getTextSize() * 3, paintWave);
    } else {
        canvas.drawText(100 / average * i + "%", width / average * i - paintWave.getTextSize() / 2, (height >> 1) + paintWave.getTextSize() * 3, paintWave);
    }
}

3.圆点的状态

起初想的是监听进度来动态转换, 这样就多出了个回调, 后来想着就直接在onDrawgetProgress()获取就好了,代码如下

image.png 到此初步搞定

项目地址