直接上效果:
分五部分:绘制文字、绘制已完成进度,间隙,未完成进度,下面的小三角
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画文字
drawText(canvas);
progress = textWidth * index + textWidth / 2;
//画左边的线
drawLeftLine(canvas);
drawMidLine(canvas);
drawRightLine(canvas);
drawTriangle(canvas);
}
/**
* 绘制文字
* @param canvas
*/
private void drawText(Canvas canvas) {
if (textList.size() > 0) {
textWidth = mWidth / textList.size();
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
for (int i = 0; i < textList.size(); i++) {
String text = textList.get(i);
float size = text.length() * textSize;
//为保证间隙在中间
canvas.drawText(textList.get(i),
paddingLeft + textWidth * i + textWidth / 2 - size / 2, textSize, mPaint);
}
}
}
/**
* 绘制三角
* @param canvas
*/
private void drawTriangle(Canvas canvas) {
float startX = progress;
float startY = textSize + TEXT_LINE_SPAEC + progressHeight;
float leftX = progress - angleSize;
float leftY = textSize + TEXT_LINE_SPAEC + progressHeight + angleSize;
float rightX = progress + angleSize;
float rightY = textSize + TEXT_LINE_SPAEC + progressHeight + angleSize;
mPaint.setColor(angleColor);
//实例化路径
Path path = new Path();
path.moveTo(startX, startY);// 此点为多边形的起点
path.lineTo(leftX, leftY);
path.lineTo(rightX, rightY);
path.close(); // 使这些点构成封闭的多边形
canvas.drawPath(path, mPaint);
}
/**
* 未完成的进度条
* @param canvas
*/
private void drawRightLine(Canvas canvas) {
float left = progress + spaceWidth / 2;
float top = textSize + TEXT_LINE_SPAEC;
float right = mWidth;
float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
mPaint.setColor(rightColor);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(left, top, right, bottom, mPaint);
}
/**
* 中间间隙
* @param canvas
*/
private void drawMidLine(Canvas canvas) {
float left = progress - spaceWidth / 2;
float right = progress + spaceWidth / 2;
float top = textSize + TEXT_LINE_SPAEC;
float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
Log.e("angle:", "----------" + left);
mPaint.setColor(spaceColor);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(left, top, right, bottom, mPaint);
}
/**
* 完成的进度条
* @param canvas
*/
private void drawLeftLine(Canvas canvas) {
float left = paddingLeft;
float right = progress - spaceWidth / 2;
float top = textSize + TEXT_LINE_SPAEC;
float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
mPaint.setColor(leftColor);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(left, top, right, bottom, mPaint);
}
attrs文件:
<declare-styleable name="ProgressView">
<attr name="progressHeight" format="dimension" />
<attr name="textSize" format="dimension" />
<attr name="textColor" format="color" />
<attr name="spaceColor" format="color" />
<attr name="spaceWidth" format="dimension" />
<attr name="angleHeight" format="dimension" />
<attr name="finishColor" format="color" />
<attr name="noFinishColor" format="color" />
<attr name="angleColor" format="color" />
</declare-styleable>
在7.0以上View运行机制发生改变在onMeasure()方法中获取的view宽度为0,导致绘制全部重叠,解决方案如下
/**
* 解决7.0以上获取宽为0的情况
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mWidth = getMeasuredWidth();
invalidate();
}
}
});
}
具体使用可以移步demo