android 自定义蜘蛛网状图形

话不都说,先上图

如图所示,玩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);
        }

    }
}

以上是完整代码,不难,步骤很明确。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值