效果展示

代码实现
package com.soface.chartdemo.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.List;
public class RadarChartView2 extends View {
public RadarChartView2(Context context) {
this(context,null);
}
public RadarChartView2(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public RadarChartView2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private int widthMode;
private int heightMode;
private int widthSize;
private int heightSize;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
widthMode = MeasureSpec.getMode(widthMeasureSpec);
heightMode = MeasureSpec.getMode(heightMeasureSpec);
widthSize = MeasureSpec.getSize(widthMeasureSpec);
heightSize = MeasureSpec.getSize(heightMeasureSpec);
intiConstant();
initPaint();
}
private float RADIUS =0;
private float cX=0;
private float cY=0;
private float LADDER=5;
private float DATA_MAX=100;
private void intiConstant() {
if (widthSize>heightSize){
RADIUS =heightSize/2f-20;
}else {
RADIUS =widthSize/2f-20;
}
cX=widthSize/2f;
cY=heightSize/2f;
}
private Paint linePaint1;
private Paint textPaint;
private Paint dataPaint;
private void initPaint() {
linePaint1 =new Paint();
linePaint1.setColor(Color.parseColor("#8F8F8F"));
linePaint1.setStyle(Paint.Style.STROKE);
linePaint1.setStrokeWidth(2);
linePaint1.setAntiAlias(true);
PathEffect effects = new DashPathEffect(new float[]{5, 10}, 0);
linePaint1.setPathEffect(effects);
textPaint =new Paint();
textPaint.setColor(Color.parseColor("#393939"));
textPaint.setTextSize(30);
linePaint1.setStrokeWidth(2);
dataPaint =new Paint();
dataPaint.setColor(Color.parseColor("#03A9F4"));
dataPaint.setStyle(Paint.Style.STROKE);
dataPaint.setStrokeWidth(4);
dataPaint.setAntiAlias(true);
dataPaint.setStyle(Paint.Style.FILL_AND_STROKE);
dataPaint.setStrokeJoin(Paint.Join.ROUND);
}
private List<Integer> dataList;
public void setData(List<Integer> list){
dataList=list;
postInvalidate();
}
private List<String> functionsList;
private String unit="";
public void setFunction(List<String> list,String unit){
functionsList=list;
this.unit=unit;
postInvalidate();
}
private float onceAngle=0;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (functionsList==null || functionsList.size()==0)return;
if (dataList==null || dataList.size()==0)return;
if (dataList.size() != functionsList.size())return;
float functionsSize=functionsList.size();
onceAngle=360/functionsSize;
for (int k=0;k<functionsList.size();k++){
float lineEndX = cX + RADIUS * (float) Math.cos((k*onceAngle) / 180 * Math.PI);
float lineEndY = cY + RADIUS * (float) Math.sin((k*onceAngle) / 180 * Math.PI);
canvas.drawLine(cX,cY,lineEndX,lineEndY,linePaint1);
if (lineEndX>cX){
textPaint.setColor(Color.parseColor("#393939"));
canvas.drawText(functionsList.get(k),lineEndX+40,lineEndY,textPaint);
}else {
textPaint.setColor(Color.parseColor("#393939"));
canvas.drawText(functionsList.get(k),lineEndX-80,lineEndY,textPaint);
}
}
float onceLadderRadius=RADIUS/LADDER;
int ladderData= (int) (DATA_MAX/LADDER);
for (int k=0;k<LADDER;k++){
float textX = cX + (onceLadderRadius*k) * (float) Math.cos((0) / 180 * Math.PI);
float textY = cY + (onceLadderRadius*k) * (float) Math.sin((0) / 180 * Math.PI);
if (k==LADDER-1){
textPaint.setColor(Color.parseColor("#FF5722"));
canvas.drawText(ladderData*k+"("+unit+")",textX,textY,textPaint);
}else {
textPaint.setColor(Color.parseColor("#FF5722"));
canvas.drawText(ladderData*k+"",textX,textY,textPaint);
}
}
for (int k=0;k<LADDER;k++){
if (k==0)linePaint1.setColor(Color.parseColor("#FF5722"));
if (k==1)linePaint1.setColor(Color.parseColor("#FF9800"));
if (k==2)linePaint1.setColor(Color.parseColor("#CDDC39"));
if (k==3)linePaint1.setColor(Color.parseColor("#4CAF50"));
if (k==4)linePaint1.setColor(Color.parseColor("#03A9F4"));
if (k>=5)linePaint1.setColor(Color.parseColor("#8F8F8F"));
for (int a=0;a<functionsList.size();a++){
float startX=cX + (onceLadderRadius*k) * (float) Math.cos((a*onceAngle) / 180 * Math.PI);
float startY=cY + (onceLadderRadius*k) * (float) Math.sin((a*onceAngle) / 180 * Math.PI);
float endX=cX + (onceLadderRadius*k) * (float) Math.cos(((a+1)*onceAngle) / 180 * Math.PI);
float endY=cY + (onceLadderRadius*k) * (float) Math.sin(((a+1)*onceAngle) / 180 * Math.PI);
Path path=new Path();
path.moveTo(startX,startY);
path.lineTo(endX,endY);
canvas.drawPath(path,linePaint1);
}
}
float dataStep=RADIUS/DATA_MAX;
for (int k=0;k<dataList.size();k++){
if (k!=dataList.size()-1){
float startX = cX + (dataStep*dataList.get(k)) * (float) Math.cos((k*onceAngle) / 180 * Math.PI);
float startY = cY + (dataStep*dataList.get(k)) * (float) Math.sin((k*onceAngle) / 180 * Math.PI);
float endX = cX + (dataStep*dataList.get(k+1)) * (float) Math.cos(((k+1)*onceAngle) / 180 * Math.PI);
float endY = cY + (dataStep*dataList.get(k+1)) * (float) Math.sin(((k+1)*onceAngle) / 180 * Math.PI);
Path path=new Path();
path.moveTo(startX,startY);
path.lineTo(endX,endY);
canvas.drawPath(path,dataPaint);
canvas.drawCircle(startX,startY,6,dataPaint);
}else {
float startX = cX + (dataStep*dataList.get(k)) * (float) Math.cos((k*onceAngle) / 180 * Math.PI);
float startY = cY + (dataStep*dataList.get(k)) * (float) Math.sin((k*onceAngle) / 180 * Math.PI);
float endX = cX + (dataStep*dataList.get(0)) * (float) Math.cos((0*onceAngle) / 180 * Math.PI);
float endY = cY + (dataStep*dataList.get(0)) * (float) Math.sin((0*onceAngle) / 180 * Math.PI);
Path path=new Path();
path.moveTo(startX,startY);
path.lineTo(endX,endY);
canvas.drawPath(path,dataPaint);
canvas.drawCircle(startX,startY,6,dataPaint);
}
}
}
}
使用方法
- 在xml中引用
<com.soface.chartdemo.view.RadarChartView2
android:id="@+id/radar2"
android:layout_margin="20px"
android:layout_width="match_parent"
android:layout_height="600px"/>
- 注入数据
private List<