自己做的一个多边形图表,效果如下
请大家下载代码查看,博客里只复制部分代码。
代码下载:
自定义view – 六边形图表 - 下载频道 - CSDN.NET
http://download.csdn.net/detail/baidu_31093133/9893021
只要给每一个维度传入不同的数值就可以显示不同的等级了。
实现步骤:
1、绘制六边形
2、绘制中心线
3、绘制文字
4、绘制等级
//绘制多边形 传入的参数是canvas和六边形的半径
private void drawPolygon(Canvas canvas, float radius) {
Path path = new Path();
path.moveTo(center, center - radius);
for (int i = 0; i < 6; i++) {
endX = (float) (center + radius * Math.sin(hudu * i));
endY = (float) (center - radius * Math.cos(hudu * i));
path.lineTo(endX, endY);
}
path.close();
canvas.drawPath(path, polygonPaint);
}
解释:
1、double hudu = Math.PI / 3;
2、center是画布的中心点,在onMeasure方法中获取。
3、使用path绘制六边形的关键是根据三角函数获得六个点的坐标。
得到六个点的坐标之后,就可以使用Path绘制出六边形了。如果我们要绘制实心六边形,需要将Paint的style设置为FILL。如果是空心则设置为STROKE
//绘制多边形的中心线
private void drawCenterLine(Canvas canvas) {
canvas.save();
canvas.rotate(0, center, center);
//lineEndY = getPaddingTop() + str_rect.height() * 2;
lineEndY = center - r1;
for (int i = 0; i < 6; i++) {
canvas.drawLine(center, center, center, lineEndY, centerLinePaint);
canvas.rotate(degree, center, center);
}
canvas.restore();
}
解释:
1、degree = 60; lineEndY是线的终点Y坐标。
2、每次将画布旋转60度,再次绘制中心线,
中心线的起点坐标为center,center,也就是六边形的中心点
中心线的终点坐标为center,center-r1.
解释:文字和六边形之间有一个文字矩阵的距离,文字矩阵指的就是以文字的的宽、高形成的绘制矩行区域。
//绘制标题
private void drawTitle(Canvas canvas) {
canvas.drawText(strs[0], center - str_rect.width() / 2, (float) (getPaddingTop() + str_rect.height()), strPaint);
canvas.drawText(strs[1], (float) ((center + r1 * Math.sin(hudu)) + str_rect.width() / 2), (float) (center - r1 * Math.cos(hudu)), strPaint);
canvas.drawText(strs[2], (float) ((center + r1 * Math.sin(hudu * 2)) + str_rect.width() / 2), (float) (center - r1 * Math.cos(hudu * 2)), strPaint);
canvas.drawText(strs[3], center - str_rect.width() / 2, (float) center + getPaddingTop() + r1 + str_rect.height(), strPaint);
canvas.drawText(strs[4], (float) ((center + r1 * Math.sin(hudu * 4)) - str_rect.width() * 1.5), (float) (center - r1 * Math.cos(hudu * 4)), strPaint);
canvas.drawText(strs[5], (float) ((center + r1 * Math.sin(hudu * 5)) - str_rect.width() * 1.5), (float) (center - r1 * Math.cos(hudu * 5)), strPaint);
}
这里的难点就是根据三角函数确定每一个文字标题的坐标。大家可以自己计算一下,就不再解释了,偷个懒(^__^) 。
//绘制等级
private void drawRank(Canvas canvas) {
Path path = new Path();
//起始坐标
path.moveTo(center, center - r1 * ranks[0] / 100);
for (int i = 0; i < 6; i++) {
rankRadius = r1 * ranks[i] / 100;
endX = (float) (center + rankRadius * Math.sin(hudu * i));
endY = (float) (center - rankRadius * Math.cos(hudu * i));
path.lineTo(endX, endY);
}
path.close();
canvas.drawPath(path, polygonPaint);
}
将最大的六边形的半径r1分为100等份,根据传入的值,确定坐标。
比如传入的值是 击杀 50。
那么第一个点的坐标就是:
x = center ; y = center - r1 * 50 /100;
然后利用三角函数计算出每一个点的坐标。
最后利用path将这些点连接起来,使用path.close();闭合路径。
设置画笔模式为STROKE,绘制空心六边形。
最后的最后把用到的各种变量,例如颜色值,文字内容,文字大小,文字颜色,六边形颜色,等级六边形的颜色,中心线的颜色等等开放一个接口出来,就可以随意定制自己的六边形图表了。
不要在onDraw方法里声明变量,减少内存开销。
自定义view性能优化:
onDraw方法里 1、减少计算时间 2、减少绘制时间 3、不要每次绘制都产生一个对象,这样会增加内存消耗。
以上就是自定义view,六边形图表的实现方式。