前面有一篇文章寫過一篇自定義View的指示條,現(xiàn)在需求改了,換上了另外一種,如下圖



發(fā)現(xiàn)之前的用不上了,不過也沒什么關(guān)系,canvas跟paint是如此的強大,以至于我們還是很輕松的能夠?qū)崿F(xiàn)它,看看實現(xiàn)的效果

跟UI還是有些差距,因為UI的字體跟顏色還沒有標注,所以后續(xù)調(diào)整一下基本上就OK了。
下面簡單說下實現(xiàn)的思路:
定義屬性
最重要的一個屬性就是當(dāng)前的進度處于哪一個位置,我們用currentNumber來表示,然后顏色什么的可以自己配置,這里就不說了
<attr name="currentNumber" format="integer"/>
onMeasure
這里沒有去做一些很復(fù)雜的判斷,因為通常進度指示條的寬度都是匹配父容器的,頂多兩邊有間距來著,所以基本上都是匹配父容器,高度也是固定的,所以寬和高的測量模式應(yīng)該都是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像素
設(shè)置畫筆
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);第一個點 完成閉環(huán)
開始繪制
mPaint.setColor(Color.BLUE);
canvas.drawPath(path, mPaint);
后面的第二個、第三個也是同樣的方法進行繪制,需要重新設(shè)置一下顏色,這里需要判斷一下當(dāng)前的進度,根據(jù)當(dāng)前的進度動態(tài)地去設(shè)置相應(yīng)的畫筆的顏色,不能寫死以免后續(xù)可以動態(tài)拓展
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坐標以及需要繪制的文字(都可以動態(tài)配置)
for (int i = 0; i < 3; i++) {
switch (i) {
case 0:
text = "驗證手機";
x = edgeWidth / 2;
break;
case 1:
text = "重設(shè)密碼";
x = edgeWidth + 6 + getHeight() / 2 + edgeWidth / 2;
break;
case 2:
x = (edgeWidth + 6) * 2 + getHeight() / 2 + (edgeWidth - getHeight() / 2) / 2;
text = "設(shè)置成功";
break;
}
設(shè)置畫筆顏色(在集合里面判斷)
if (i > currentNumber) {
mPaint.setColor(Color.BLACK);
} else {
mPaint.setColor(Color.WHITE);
}
繪制文字
canvas.drawText(text, x, baseY, mPaint);
到這里基本上,繪制完成了,比較簡單,主要是path的簡單使用,記錄一下