就直接上代码啦,注释都写的很详细了的
package com.mvp.viewdemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.View; /** * <h3>Description</h3> * <p> * 雷达图 * <p> * <h3>Author</h3> cgc * <h3>Date</h3> 2016/11/17 13:53 * <h3>Copyright</h3> Copyright (c)2016 Shenzhen JJshome Technology Co., Ltd. Inc. All rights reserved. */ public class RadarView extends View { public RadarView(Context context) { this(context, null); } public RadarView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadarView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } /** 绘制连线画笔 */ private Paint mLienPaint; /** 绘制数据点画笔 */ private Paint mDataPaint; /** 绘制文本画笔 */ private Paint mTextPaint; /** 中心点 x */ private int centreX; /** 中心点y */ private int centreY; /** 半径 */ private float radius = 0; /** 数据点半径 */ private float dataRadius = 10; /** 数据区透明值 最大255 不透明 */ private int dataAlpha = 127; /** 字体大小 */ private int textSize = 38; /** 连线颜色 */ private int lienColor = Color.GRAY; /** 数据点颜色 */ private int dataColor = Color.GREEN; /** 数据区颜色 */ private int dataAreaColor = Color.YELLOW; /** 数据点之间的连线颜色 */ private int dataPointLienColor = Color.RED; /** 文本颜色 */ private int textColor = Color.BLACK; /** 雷达图占界面的比例 默认0.8 */ private float occupyRatio = 0.8f; /** 根据数据设置纬度 */ private boolean isValuesToCount = false; /** 纬度数 */ private int count = 8; /** 计算角度 */ private float angle = (float) (Math.PI * 2 / count); /** 最大值 */ private int maxValue = 100; /** 数值 */ private double[] values = null; private void init() { //初始化绘制连接的画笔 mLienPaint = new Paint(); mLienPaint.setAntiAlias(true); mLienPaint.setStyle(Paint.Style.STROKE); mLienPaint.setColor(lienColor); //初始化绘制数据的画笔 mDataPaint = new Paint(); mDataPaint.setAntiAlias(true); mDataPaint.setStyle(Paint.Style.STROKE); mDataPaint.setColor(dataColor); //初始化绘制文字的画笔 mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setStyle(Paint.Style.STROKE); mTextPaint.setColor(textColor); mTextPaint.setTextSize(textSize); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); radius = Math.min(w, h) / 2 * occupyRatio; centreX = w / 2; centreY = h / 2; // postInvalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawLien(canvas); drawToLien(canvas); drawText(canvas); if (values != null && values.length > 0) { drawValue(canvas); } } /** * 绘制数据区 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:40 * <h3>UpdateTime</h3> 2016/11/17,16:40 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param canvas */ private void drawValue(Canvas canvas) { Path path = new Path(); for (int i = 0; i < count; i++) { //计算数据值所占的比例 double percent = values[i] / maxValue; //计算坐标 float x = (float) (centreX + radius * Math.cos(angle * i) * percent); float y = (float) (centreY + radius * Math.sin(angle * i) * percent); if (i == 0) {//设置起点 path.moveTo(x, centreY); } else { //记录数据点 if (values[i] != 0) { path.lineTo(x, y); } } //绘制数据点 if (values[i] != 0) { mDataPaint.setStyle(Paint.Style.FILL); mDataPaint.setColor(dataColor); canvas.drawCircle(x, y, dataRadius, mDataPaint); } } //闭合路径,连接数据点 path.close(); mDataPaint.setColor(dataPointLienColor); mDataPaint.setStyle(Paint.Style.STROKE); canvas.drawPath(path, mDataPaint); //绘制数据点之间区域的面积 mDataPaint.setColor(dataAreaColor); mDataPaint.setAlpha(dataAlpha); mDataPaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawPath(path, mDataPaint); } /** * 数据点的半径 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:56 * <h3>UpdateTime</h3> 2016/11/17,16:56 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param dataRadius */ public void setDataRadius(float dataRadius) { this.dataRadius = dataRadius; } /** * 数据区域的透明值 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:56 * <h3>UpdateTime</h3> 2016/11/17,16:56 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param dataAlpha 1-255 1为全透明,255未透明 */ public void setDataAlpha(int dataAlpha) { this.dataAlpha = dataAlpha; } /** * 设置字体大小 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:32 * <h3>UpdateTime</h3> 2016/11/17,17:32 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param textSize */ public void setTextSize(int textSize) { this.textSize = textSize; } /** * 设置雷达图连接颜色 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:33 * <h3>UpdateTime</h3> 2016/11/17,17:33 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param lienColor */ public void setLienColor(int lienColor) { mLienPaint.setColor(lienColor); } /** * 设置数据点颜色 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:33 * <h3>UpdateTime</h3> 2016/11/17,17:33 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param dataColor */ public void setDataColor(int dataColor) { this.dataColor = dataColor; } /** * 设置数据区颜色 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:34 * <h3>UpdateTime</h3> 2016/11/17,17:34 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param dataAreaColor */ public void setDataAreaColor(int dataAreaColor) { this.dataAreaColor = dataAreaColor; } /** * 设置数据点颜色 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:34 * <h3>UpdateTime</h3> 2016/11/17,17:34 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param dataPointLienColor */ public void setDataPointLienColor(int dataPointLienColor) { this.dataPointLienColor = dataPointLienColor; } /** * 设置字体颜色 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:34 * <h3>UpdateTime</h3> 2016/11/17,17:34 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param textColor */ public void setTextColor(int textColor) { this.textColor = textColor; } /** * 雷达图占界面的比例 默认0.8 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:34 * <h3>UpdateTime</h3> 2016/11/17,17:34 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param occupyRatio */ public void setOccupyRatio(float occupyRatio) { this.occupyRatio = occupyRatio; } /** * 设置纬度值 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:35 * <h3>UpdateTime</h3> 2016/11/17,17:35 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param count */ public void setCount(int count) { if (!isValuesToCount) { this.count = count; } } /** * 设置最大值 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:35 * <h3>UpdateTime</h3> 2016/11/17,17:35 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param maxValue */ public void setMaxValue(int maxValue) { this.maxValue = maxValue; } /** * 数值 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:35 * <h3>UpdateTime</h3> 2016/11/17,17:35 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param values */ public void setValues(double[] values) { this.values = values; this.count = values.length; } /** * 是否根据数值设置纬度 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:39 * <h3>UpdateTime</h3> 2016/11/17,17:39 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param values 数据值 * @param isValuesToCount 是否根据数据值数量设置纬度数 true是(如果是true setCount 设置纬度将失效) false 不是 */ public void setValues(double[] values, boolean isValuesToCount) { this.values = values; if (isValuesToCount) { this.count = values.length; } this.isValuesToCount = isValuesToCount; } /** * 绘制雷达图 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,17:36 * <h3>UpdateTime</h3> 2016/11/17,17:36 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) */ public void startInvalidate() { angle = (float) (Math.PI * 2 / count); invalidate(); } /** * 绘制文本 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:42 * <h3>UpdateTime</h3> 2016/11/17,16:42 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param canvas */ private void drawText(Canvas canvas) { //获取画笔的适量 Paint.FontMetrics fm = mTextPaint.getFontMetrics(); //计算文本的高度 float fontHeight = fm.descent - fm.ascent; for (int i = 0; i < count; i++) { //计算坐标 float x = (float) (centreX + (radius + fontHeight / 2) * Math.cos(angle * i)); float y = (float) (centreY + (radius + fontHeight / 2) * Math.sin(angle * i)); if (i == 0) {//绘制第一项 canvas.drawText(i + "", x, y + (fontHeight / 2) / 2, mTextPaint); } else if (i == 3) {//绘制第三项 canvas.drawText(i + "", x - 20, y + (fontHeight / 2) / 2, mTextPaint); } else if (i == 2 || i == 1) {//绘制第二,一项 canvas.drawText(i + "", x, y + (fontHeight / 2), mTextPaint); } else { canvas.drawText(i + "", x, y, mTextPaint); } } } /** * 绘制雷达图的层次 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:44 * <h3>UpdateTime</h3> 2016/11/17,16:44 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param canvas */ private void drawLien(Canvas canvas) { //层次之间的距离 float r = radius / (count - 1); //绘制路径 Path path = new Path(); for (int i = 1; i < count; i++) { //层次的半径 float newRadius = r * i; path.reset(); for (int j = 0; j < count; j++) { if (j == 0) {//绘制起点 path.moveTo(centreX + newRadius, centreY); } else { //计算角度的坐标 float x = (float) (centreX + newRadius * Math.cos(angle * j)); float y = (float) (centreY + newRadius * Math.sin(angle * j)); //进行连线 path.lineTo(x, y); } } //闭合路径 path.close(); canvas.drawPath(path, mLienPaint); } } /** * 绘制中心点到纬度点的连接 * <p> * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/11/17,16:44 * <h3>UpdateTime</h3> 2016/11/17,16:44 * <h3>CreateAuthor</h3> cgc * <h3>UpdateAuthor</h3> cgc * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * * @param canvas */ private void drawToLien(Canvas canvas) { Path path = new Path(); for (int i = 0; i < count; i++) { path.reset(); path.moveTo(centreX, centreY); float x = (float) (centreX + radius * Math.cos(angle * i)); float y = (float) (centreY + radius * Math.sin(angle * i)); path.lineTo(x, y); path.close(); canvas.drawPath(path, mLienPaint); } } }