前面有一篇文章写过一篇自定义View的指示条,现在需求改了,换上了另外一种,如下图
发现之前的用不上了,不过也没什么关系,canvas跟paint是如此的强大,以至于我们还是很轻松的能够实现它,看看实现的效果
跟UI还是有些差距,因为UI的字体跟颜色还没有标注,所以后续调整一下基本上就OK了。
下面简单说下实现的思路:
定义属性
最重要的一个属性就是当前的进度处于哪一个位置,我们用currentNumber来表示,然后颜色什么的可以自己配置,这里就不说了
复制代码
onMeasure
这里没有去做一些很复杂的判断,因为通常进度指示条的宽度都是匹配父容器的,顶多两边有间距来着,所以基本上都是匹配父容器,高度也是固定的,所以宽和高的测量模式应该都是MeasureSpec.EXACTLY,所以就没有进行额外处理,如果需要的话跟一样,将MeasureSpec.EXACTLY中的宽度或者高度进行累加就好了,不在多言
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); }复制代码
onDraw
这个里面进行绘制的时候跟之前的稍微不一样,需要用到Path这个类来绘制多边形,需要绘制三个多边形,多边形的绘制主要是对描述的点正确定位,其余的没什么难度
- 第一个多边形
先计算出三条多边形每条边的宽度
int edgeWidth = (getWidth() - 12) / 3; //中间的间隔是每个6像素复制代码
设置画笔
mPaint = new Paint(); mPaint.setStrokeWidth((float) 3.0); mPaint.setStyle(Paint.Style.FILL);复制代码
定点连线
Path path = new Path(); path.moveTo(0, 0); //第一个点 path.lineTo(edgeWidth, 0);//第二个点 path.lineTo(edgeWidth + getHeight() / 2, getHeight() / 2); //第三个点 path.lineTo(edgeWidth, getHeight()); //第四个点 path.lineTo(0, getHeight()); //第五个点 path.lineTo(0, 0);第一个点 完成闭环复制代码
开始绘制
mPaint.setColor(Color.BLUE); canvas.drawPath(path, mPaint);复制代码
后面的第二个、第三个也是同样的方法进行绘制,需要重新设置一下颜色,这里需要判断一下当前的进度,根据当前的进度动态地去设置相应的画笔的颜色,不能写死以免后续可以动态拓展
2.绘制文字
初始化画笔
mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setTextSize(34);复制代码
计算基线坐标
String text = new String("验证手机"); mPaint.measureText(text); Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); int textHeight = (int) (fontMetrics.bottom - fontMetrics.top);// x坐标 int baseY = (int) (textHeight / 2 + getHeight() / 2 - fontMetrics.bottom);//基线位置复制代码
计算起始点X坐标以及需要绘制的文字(都可以动态配置)
for (int i = 0; i < 3; i++) { switch (i) { case 0: text = "验证手机"; x = edgeWidth / 2; break; case 1: text = "重设密码"; x = edgeWidth + 6 + getHeight() / 2 + edgeWidth / 2; break; case 2: x = (edgeWidth + 6) * 2 + getHeight() / 2 + (edgeWidth - getHeight() / 2) / 2; text = "设置成功"; break; }复制代码
设置画笔颜色(在集合里面判断)
if (i > currentNumber) { mPaint.setColor(Color.BLACK); } else { mPaint.setColor(Color.WHITE); }复制代码
绘制文字
canvas.drawText(text, x, baseY, mPaint);复制代码
到这里基本上,绘制完成了,比较简单,主要是path的简单使用,记录一下