前面有一篇文章写过一篇自定义View的指示条,现在需求改了,换上了另外一种,如下图
发现之前的用不上了,不过也没什么关系,canvas跟paint是如此的强大,以至于我们还是很轻松的能够实现它,看看实现的效果
跟UI还是有些差距,因为UI的字体跟颜色还没有标注,所以后续调整一下基本上就OK了。
下面简单说下实现的思路:
定义属性
最重要的一个属性就是当前的进度处于哪一个位置,我们用currentNumber来表示,然后颜色什么的可以自己配置,这里就不说了
<attr name="currentNumber" format="integer"/>
onMeasure
这里没有去做一些很复杂的判断,因为通常进度指示条的宽度都是匹配父容器的,顶多两边有间距来着,所以基本上都是匹配父容器,高度也是固定的,所以宽和高的测量模式应该都是MeasureSpec.EXACTLY,所以就没有进行额外处理,如果需要的话跟自定义View之IndexView进度条(一)一样,将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的简单使用,记录一下