项目需要画一个蜘蛛图,补了下蛋疼的三角函数,效果图如图所示:
本文主要是提供画基础自定义view的思路,通过这种思路,从而实现复杂的自定义view,分为以下几个步骤:
绘制正多边形
/**
* 绘制正多边形
*/
private void drawPolygon(Canvas canvas) {
Path path = new Path();
float r = radius / (count - 1);
for (int i = 1; i <= count; i++) {
float curR = r * i;
path.reset();
for (int j = 1; j <= count; j++) {
float x = (float) (centerX + curR * Math.sin(angle * j));
float y = (float) (centerY - curR * Math.cos(angle * j));
if (j == 1) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
if (i == count) {
drawPoint(canvas, x, y);
}
}
path.close();
canvas.drawPath(path, mainPaint);
}
}
绘制直线
/**
* 绘制直线
*/
private void drawLines(Canvas canvas) {
Path path = new Path();
for (int i = 1; i <= count; i++) {
path.reset();
path.moveTo(centerX, centerY);
float x = (float) (centerX + maxRadius * Math.sin(angle * i));
float y = (float) (centerY - maxRadius * Math.cos(angle * i));
path.lineTo(x, y);
canvas.drawPath(path, mainPaint);
}
}
绘制文字
/**
* 绘制文字
* 其实四个象限,是以(centerX, centerY)为圆点的象限
*
* @param canvas
*/
private void drawText(Canvas canvas) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float fontHeight = fontMetrics.descent - fontMetrics.ascent;
for (int i = 1; i <= count; i++) {
float x = (float) (centerX + (maxRadius + fontHeight / 2) * Math.sin(angle * i));
float y = (float) (centerY - (maxRadius + fontHeight / 2) * Math.cos(angle * i));
float relateX = x - centerX;
float relateY = y - centerY;
if (relateX >= 0 && relateY >= 0) {//第4象限
canvas.drawText(titles[i - 1], x, y, textPaint);
} else if (relateX < 0 && relateY >= 0) {//第3象限
float dis = textPaint.measureText(titles[i - 1]);//文本长度
canvas.drawText(titles[i - 1], x - dis, y, textPaint);
} else if (relateX < 0 && relateY < 0) {//第2象限
float dis = textPaint.measureText(titles[i - 1]);//文本长度
canvas.drawText(titles[i - 1], x - dis, y, textPaint);
} else if (relateX >= 0 && relateY < 0) {//第1象限
float dis = textPaint.measureText(titles[i - 1]);//文本长度
canvas.drawText(titles[i - 1], x - dis / 2, y, textPaint);
}
}
}
绘制中间有效区域
/**
* 绘制中间有效区域
*
* @param canvas
*/
private void drawRegion(Canvas canvas) {
Path path = new Path();
valuePaint.setAlpha(255);
for (int i = 1; i <= count; i++) {
double percent = data[i - 1] / maxValue;
float x = (float) (centerX + maxRadius * Math.sin(angle * i) * percent);
float y = (float) (centerY - maxRadius * Math.cos(angle * i) * percent);
if (i == 1) {
path.moveTo(x, y);
} else {
path.lineTo(x, y);
}
}
valuePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, valuePaint);
valuePaint.setAlpha(127);
//绘制填充区域
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path, valuePaint);
}