Android自定义View——雷达图

在这里插入图片描述
分析

  • 绘制雷达背景图 drawline
  • 绘制文字标签 drawText
  • 填充雷达数据 drawPath
  • 描点 drawPoint

在这里插入图片描述
全部代码如下所示:
如果要修改为五边形、四边形,只要将borderCount 修改为相应值即可
另外数据源的个数要大于等于borderCount,不然会空指针异常,请自己做好兼容性处理

public class RadarView extends View {

    //雷达填充颜色
    private int FILL_COLOR = 0x7f00574B;
    //雷达描点
    private int POINT_COLOR = 0xff008577;


    //控件大小
    private int width;
    private int height;
    //控件雷达最大边长
    private int maxRadius;
    private int margin = 70; //px,dp需要自己转换
    //N边形
    private int borderCount = 6;
    //环线个数
    private int circleCount = 5;
    //an angle, in radians,与borderCount相关
    private double angle;

    private int titleTxSize = 28; //px,sp需要自己转换
    private int pointSize = 8; //px,dp需要自己转换
    //标签值
    private String[] mTitles = {"a", "b", "c", "d", "e", "f"};
    //数据值,个数应该要和borderCount保持一致,不然要做兼容性处理
    private int[] mData = new int[]{100, 60, 60, 60, 100, 70};
    //数据最大值
    private int maxValue = 100;

    //画笔
    private Paint paint;
    private Path path;


    public RadarView(Context context) {
        super(context, null);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.GRAY);
        paint.setAntiAlias(true);
        path = new Path();

        angle = 2 * Math.PI / borderCount;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        maxRadius = (Math.min(width, height) - margin) / 2;
        //坐标系移动到控件中心
        canvas.translate(width / 2, height / 2);
        //绘制雷达
        for (int j = 0; j < borderCount; j++) {
            canvas.rotate(360 / borderCount);
            canvas.drawLine(0, 0, maxRadius, 0, paint);
            for (int i = 1; i <= circleCount; i++) {
                int circleRadius = (int) (i * 1f / circleCount * maxRadius);
                float x = (float) (circleRadius * Math.cos(angle));
                float y = (float) (circleRadius * Math.sin(angle));
                canvas.drawLine(circleRadius, 0, x, y, paint);
            }
        }
        //绘制文字标签
        paint.setTextSize(titleTxSize);
        for (int i = 0; i < borderCount; i++) {
            int length = maxRadius + 20;
            int x = (int) (length * Math.cos(i * angle));
            int y = (int) (length * Math.sin(i * angle));
            canvas.drawText(mTitles[i], x, y, paint);
        }
        //绘制多边形并描点填充
        paint.setColor(POINT_COLOR);
        for (int i = 0; i < mData.length; i++) {
            float length = mData[i] * 1f / maxValue * maxRadius;
            int x = (int) (length * Math.cos(i * angle));
            int y = (int) (length * Math.sin(i * angle));
            if (i == 0) {
                path.moveTo(x, y);
            } else {
                path.lineTo(x, y);
            }
            canvas.drawCircle(x, y, pointSize, paint);
        }
//        path.close(); 填充模式下不close也不影响
//        paint.setStyle(Paint.Style.STROKE);
//        paint.setStrokeWidth(4);
        paint.setColor(FILL_COLOR);
        canvas.drawPath(path, paint);

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值