效果图:
具体实现
public class RadarView extends View {
private static final float maxValue = 100; // 最大刻度值
private int count = 5; // 数据个数
private float angle = (float) (Math.PI * 2 / count);
private Paint circlePaint; // 圆环画笔
private float radius; // 最大半径
private int centerX, centerY; // 中心点
private Paint mainCirclePaint; // 整个圆环填充画笔
private Paint graduationValuePaint; // 刻度值画笔
private String[] graduationValues = {"0", "20", "40", "60", "80", "100"};
private Paint titlePaint; // 标签画笔
private String[] titles = {"标签a", "标签b", "标签c", "标签d", "标签f"};
private double[] data = {70, 50, 67, 80, 56};
private Paint dotPaint; // 外环上的圆点画笔
private Paint regionPaint; // 数据区域画笔
private int ten;
public RadarView(Context context) {
super(context);
init();
}
public RadarView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
DisplayMetrics dm = getResources().getDisplayMetrics();
int screenWidth = dm.widthPixels;
ten = (int) (0.0094 * screenWidth);
// 圆环区域
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(getResources().getColor(R.color.circle_stroke_color));
circlePaint.setStyle(Paint.Style.STROKE);
mainCirclePaint = new Paint();
mainCirclePaint.setAntiAlias(true);
mainCirclePaint.setColor(getResources().getColor(R.color.circle_fill_color));
mainCirclePaint.setStyle(Paint.Style.FILL);
// 刻度值
graduationValuePaint = new Paint();
graduationValuePaint.setAntiAlias(true);
graduationValuePaint.setColor(getResources().getColor(R.color.int_value_color));
Typeface typeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
graduationValuePaint.setTypeface(typeface);
graduationValuePaint.setTextSize(18);
graduationValuePaint.setStyle(Paint.Style.FILL);
// 标签画笔
titlePaint = new Paint();
titlePaint.setAntiAlias(true);
titlePaint.setColor(getResources().getColor(R.color.black_color));
Typeface titleTypeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
titlePaint.setTypeface(titleTypeface);
titlePaint.setTextSize(24);
titlePaint.setStyle(Paint.Style.FILL);
// 外环上的圆点画笔
dotPaint = new Paint();
dotPaint.setAntiAlias(true);
dotPaint.setColor(getResources().getColor(R.color.blue_dot_color));
dotPaint.setStyle(Paint.Style.FILL);
// 数据区域画笔
regionPaint = new Paint();
regionPaint.setAntiAlias(true);
regionPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
radius = Math.min(h, w) / 2 * 0.7f;
centerX = w / 2;
centerY = h / 2;
postInvalidate();
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// 画底层圆环
drawCircle(canvas);
// 画刻度值
drawGraduationValue(canvas);
// 画文字标题
drawTitles(canvas);
// 画有效区域
drawRegion(canvas);
}
private void drawGraduationValue(Canvas canvas) {
Paint.FontMetrics fontMetrics = graduationValuePaint.getFontMetrics();
// 文本高度
float fontHeight = fontMetrics.descent - fontMetrics.ascent;
// 刻度值X轴坐标
float graduationX = centerX - fontHeight * 6 / 5;
// 网层直接距离
float r = radius / 5;
for (int i = 1; i < 6; i++) {
graduationX = graduationX + 20;
float curR = r * i;
float graduationY = centerY + curR - 20;
canvas.drawText(graduationValues[i], graduationX, graduationY, graduationValuePaint);
}
}
private void drawCircle(Canvas canvas) {
// 画带有填充色的背景圆
canvas.drawCircle(centerX, centerY, radius, mainCirclePaint);
// 画圆框
float r = radius / count;
for (int i = 1; i < 6; i++) {
float curR = i * r; // 每一个圆环的半径
canvas.drawCircle(centerX, centerY, curR, circlePaint);
}
// 画十字直线
canvas.drawLine(centerX - radius, centerY, centerX + radius, centerY, circlePaint); // 横线
canvas.drawLine(centerX, centerY - radius, centerX, centerY + radius, circlePaint); // 竖线
}
private void drawTitles(Canvas canvas) {
for (int i = 0; i < count; i++) {
float x = (float) (centerX + radius * Math.cos(angle * i));
float y = (float) (centerY + radius * Math.sin(angle * i));
Paint.FontMetrics fontMetrics = titlePaint.getFontMetrics();
// 文本高度
float fontHeight = fontMetrics.descent - fontMetrics.ascent;
Rect rect = new Rect();
titlePaint.getTextBounds(titles[i], 0, titles[i].length(), rect);
// 文本宽度
float fontWidth = rect.width();
// 文本坐标
float titleX = (float) (x + fontWidth * Math.cos(angle * i)) - (fontWidth / 2);
float titleY = (float) (y + fontHeight * Math.sin(angle * i));
canvas.drawText(titles[i], titleX, titleY, titlePaint);
// 画圆点
canvas.drawCircle(x, y, 10, dotPaint);
}
}
private void drawRegion(Canvas canvas) {
Path path = new Path();
regionPaint.setColor(getResources().getColor(R.color.region_color));
regionPaint.setAlpha(255);
for (int i = 0; i < count; i++) {
double percent = data[i] / maxValue;
float x = (float) (centerX + radius * Math.cos(angle * i) * percent);
float y = (float) (centerY + radius * Math.sin(angle * i) * percent);
if (i == 0) {
path.moveTo(x, centerY);
} else {
path.lineTo(x, y);
}
canvas.drawCircle(x, y, 10, regionPaint);
}
path.close();
regionPaint.setColor(getResources().getColor(R.color.blue_dot_color));
regionPaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, regionPaint);
// 填充色
regionPaint.setColor(getResources().getColor(R.color.region_color));
regionPaint.setStyle(Paint.Style.FILL_AND_STROKE);
regionPaint.setAlpha(127);
canvas.drawPath(path, regionPaint);
}
}
根据需要,自行修改代码即可
来源:CSDN
作者:pd啊
链接:https://blog.csdn.net/u014651178/article/details/104030924