话不都说,先上图
如图所示,玩lol的玩家都知道,战力分析图,那么怎么实现呢?
具体思路是,1.首先话六边形,用Path进行每个点的链接
2.画连接线,中心点跟最外层六边形各个顶点
3.画数据图,用path进行连接数据,然后paint采用填充模式即可
4.写文字
不多说,上代码,直接拿去用
package com.cnki.roundcake;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* 战力蜘蛛网图
* Created by liweidong on 2019/12/2.
*/
public class CombatMap extends View {
//半径
private int radius;
//中心点坐标
private int centerX,centerY;
private Paint paint;
//数值转为度数,每个角度
private double angle;
//六边形
private int count = 6;
//当前的半径
private int curRadius;
private Paint fillPaint;
private int[] datas;
private String[] texts;
private Paint textPaint;
public CombatMap(Context context) {
super(context);
init();
}
public CombatMap(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public CombatMap(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* 初始化
*/
private void init(){
paint = new Paint();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
angle = Math.toRadians(60);
fillPaint = new Paint();
fillPaint.setColor(0x5000ff00);
fillPaint.setStrokeWidth(2);
fillPaint.setStyle(Paint.Style.FILL);
textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setStrokeWidth(3);
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextSize(32);
textPaint.setTextAlign(Paint.Align.CENTER);
datas = new int[]{2,6,4,5,1,3};
texts = new String[]{"助攻", "击杀","金钱","防御","魔法","物理"};
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//计算出半径
radius = (int) (Math.min(w, h) * 0.7) / 2;
centerX = w / 2;
centerY = h / 2;
invalidate();
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawGrid(canvas);
drawLine(canvas);
drawArea(canvas);
drawText(canvas);
}
/**
* 写文字
* @param canvas
*/
private void drawText(Canvas canvas) {
for (int i = 0; i < texts.length; i++){
if (i == 0){
canvas.drawText(texts[i], centerX + radius + 32, centerY, textPaint);
}else if (i == 1 || i == 2){
canvas.drawText(texts[i], (float) (centerX + radius * Math.cos(angle * i)), (float) (centerY + radius * Math.sin(angle * i) + 32), textPaint);
}else if (i == 3){
canvas.drawText(texts[i], centerX - radius - 32, centerY, textPaint);
}else {
canvas.drawText(texts[i], (float) (centerX + radius * Math.cos(angle * i)), (float) (centerY + radius * Math.sin(angle * i) - 10), textPaint);
}
}
}
/**
* 画填充区域
* @param canvas
*/
private void drawArea(Canvas canvas) {
Path path = new Path();
for (int i = 0; i < datas.length; i++){
if (i == 0){
path.moveTo(centerX + datas[i] * radius / 6, centerY);
}else{
path.lineTo((float) (centerX + datas[i] * radius / 6 * Math.cos(angle * i)), (float)(centerY + datas[i] * radius / 6 * Math.sin(angle * i)));
}
}
canvas.drawPath(path, fillPaint);
}
/**
* 画线
* @param canvas
*/
private void drawLine(Canvas canvas) {
Path path = new Path();
for (int i = 0; i < count; i++){
path.reset();
path.moveTo(centerX, centerY);
if (i == 0){
path.lineTo(centerX + radius, centerY);
}else{
path.lineTo((float) (centerX + radius * Math.cos(angle * i)), (float) (centerY + radius * Math.sin(angle * i)));
}
canvas.drawPath(path, paint);
}
}
/**
* 绘制蜘蛛网格
* @param canvas
*/
private void drawGrid(Canvas canvas) {
Path path = new Path();
for (int i = 1; i < count + 1; i++){
path.reset();
curRadius = radius / count * i;
for (int j = 0; j < count; j ++){
if (j == 0){
path.moveTo(centerX + curRadius, centerY);
}else{
path.lineTo((float) (centerX + curRadius * Math.cos(angle * j)), (float) (centerY + curRadius * Math.sin(angle * j)));
}
}
path.close();
canvas.drawPath(path, paint);
}
}
}
以上是完整代码,不难,步骤很明确。