这篇文章我们就用简单的自定义View实现类似iOS11的控制中心里边出现的很新颖的进度条。

先看一下目标效果图,以及最后的实现效果:

模拟ios控制中心 仿ios控制中心app_模拟ios控制中心

模拟ios控制中心 仿ios控制中心app_android 仿京东地址选择_02

自定义属性分析


名字

释义

progressMax

最大值

progressValue

进度

iconSrc

图标

bgColor

背景颜色

progressColor

进度颜色

progressOrientation

方向

rectRadius

圆角弧度

iconPadding

icon内间距

以上总结下来,相关属性定义代码为:

进度条绘制

首先分析下进度条构成

  • 背景
  • 进度
  • Icon

看似很简单。使用canvas.drawRoundRect()分别画出背景和进度,最后追加绘制一个bitmap即可。

但实际操作中会发现如果按照Progress 覆盖 Background的思路操作起来可行性并不高。问题出在绘制Progress时,处理圆角上边。

解决办法是使用Paint.setXfermode();

这里我们用到的是PorterDuff.Mode.SRC_ATOP

这个思路用白话文描述就是:先画一个圆角背景,然后在圆角背景的基础上画矩形的Progress.这时候因为使用了Paint.setXfermode();所以矩形的Progress只有与背景相交的部分才会显示出来.

(注:使用Paint.setXfermode();需要关闭硬件加速,否则可能会不生效:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);)

那么ondraw()中绘制进度代码其实就很简单了:

//bgPaint 是背景画笔、progressPaint是进度画笔        int canvasWidth = canvas.getWidth();        int canvasHeight = canvas.getHeight();        int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);        {            bgPaint.setColor(bgColor);            // draw the background of progress            canvas.drawRoundRect(bgRect, rectRadius, rectRadius, bgPaint);            // draw progress            canvas.drawRect(progressRect, progressPaint);            bgPaint.setXfermode(null);        }        canvas.restoreToCount(layerId);

手势的处理

此处只分析垂直方向手势处理,水平方向同理:手势处理这块逻辑极为简单。逻辑上

ACTION_DOWN与ACTION_MOVE都是一样的。需要处理的只有一点:

  • 考虑到View的padding,所以首先要判断 ACTION_DOWN的时候是否是按在进度条内,如果是才做处理
    主要代码:
//bgRect背景矩形,progressRect进度矩形            if (event.getY() < bgRect.top) {                //触点超出Progress顶部                progressRect.top = bgRect.top;            } else if (event.getY() > bgRect.bottom) {                //触点超过Progress底部                progressRect.top = bgRect.bottom;            } else {                progressRect.top = getPaddingTop() + event.getY();            }

图标绘制

icon的绘制只有一行代码:
canvas.drawBitmap(bitmap, srcRect, dstRect, bgPaint);

需要解释一下的是该方法的参数。

  • srcRect 要绘制的Bitmap区域
  • dstRect Bitmp要绘制的区域

回调

要注意的是每次百分比变化才做一次回调。

源码地址:

https://github.com/CuiZhaoHui/IOS11RectProgress

到这里就结束啦.