经常会在游戏中看到用蜘蛛网图表达用户在游戏中的各种表现,感觉还蛮直观蛮有趣的,刚好最近也在学习自定义View的相关知识,就自己做一个蜘蛛网图,作为笔记了。

先放一张我感觉对自己挺有帮助,从网上找的以这个自定义View流程的图片

View最终效果

  我们可以根据我们最终的效果来分析我们应该如何怎么完成这个View。

  首先可以看到最终的View是以整个布局的中心作为坐标原点开始绘制的,所以先要确定布局中心,然后最基础的是有几个共同中心点的正六边形,再将每个六边形的顶点与中心点相连,根据数据绘制需要覆盖的区域,最后在每个顶点旁标注文字。

  整体的流程就是这样了,可以开始写代码了

定义变量和初始化

    private int count = 6;           //数据个数private float angle = (float) (Math.PI * 2 / count);private float radius;            //网格最大半径private int centerX;             //中心Xprivate int centerY;             //中心Yprivate String[] titles = {"a", "b", "c", "d", "e", "f"};                          //默认数据private double[] data = {100, 60, 60, 60, 100, 50, 10, 20};                       //默认分值private float maxValue = 100;    //数据最大值private Paint mainPaint;         //雷达区画笔private Paint valuePaint;        //数据区画笔private Paint textPaint;         //文本画笔
   private void init() {count = Math.min(data.length, titles.length);mainPaint = new Paint();mainPaint.setAntiAlias(true);mainPaint.setColor(Color.GRAY);mainPaint.setStyle(Paint.Style.STROKE);valuePaint = new Paint();valuePaint.setAntiAlias(true);valuePaint.setColor(Color.BLUE);valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);textPaint = new Paint();textPaint.setTextSize(40);textPaint.setStyle(Paint.Style.FILL);textPaint.setColor(Color.BLACK);}

确定布局中心

onSizeChanged(int w, int h, int oldw, int oldh)方法里面,根据View的长宽,获取整个布局的中心坐标

    @Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {radius = Math.min(h, w) / 2 * 0.9f;centerX = w / 2;centerY = h / 2;postInvalidate();super.onSizeChanged(w, h, oldw, oldh);}

绘制正六边形

  private void drawPolygon(Canvas canvas) {Path path = new Path();float r = radius / (count - 1);for (int i = 1; i < count; i++) {float curR = r * i;path.reset();for (int j = 0; j < count; j++) {if (j == 0) {path.moveTo(centerX + curR, centerY);} else {float x = (float) (centerX + curR * Math.cos(angle * j));float y = (float) (centerY + curR * Math.sin(angle * j));path.lineTo(x, y);}}path.close();canvas.drawPath(path, mainPaint);}}

绘制顶点到中心直线

   private void drawLines(Canvas canvas) {Path path = new Path();for (int i = 0; i < count; i++) {path.reset();path.moveTo(centerX, centerY);float x = (float) (centerX + radius * Math.cos(angle * i));float y = (float) (centerY + radius * Math.sin(angle * i));path.lineTo(x, y);canvas.drawPath(path, mainPaint);}}

绘制覆盖区域

   private void drawRegion(Canvas canvas) {Path path = new Path();valuePaint.setAlpha(255);for (int i = 0; i < count; i++) {double percent = data[i] / maxValue;float x = (float) (centerX + radius * Math.cos(angle * i) * percent);float y = (float) (centerY + radius * Math.sin(angle * i) * percent);if (i == 0) {path.moveTo(x, centerY);} else {path.lineTo(x, y);}//绘制小圆点canvas.drawCircle(x, y, 10, valuePaint);}valuePaint.setStyle(Paint.Style.STROKE);canvas.drawPath(path, valuePaint);valuePaint.setAlpha(127);//绘制填充区域valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);canvas.drawPath(path, valuePaint);}

绘制文本

对于文本的绘制,首先要找到末端的坐标,由于末端和文本有一定距离,给每个末端加上这个距离以后,再绘制文本。 另外,当文本在左边时,由于不希望文本和蜘蛛网交叉,我们可以先计算出文本的长度,然后使起始绘制坐标向左偏移这个长度。

   private void drawText(Canvas canvas) {Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();float fontHeight = fontMetrics.descent - fontMetrics.ascent;for (int i = 0; i < count; i++) {float x = (float) (centerX + (radius + fontHeight / 2) * Math.cos(angle * i));float y = (float) (centerY + (radius + fontHeight / 2) * Math.sin(angle * i));if (angle * i >= 0 && angle * i <= Math.PI / 2) {canvas.drawText(titles[i], x, y, textPaint);} else if (angle * i >= 3 * Math.PI / 2 && angle * i <= Math.PI * 2) {canvas.drawText(titles[i], x, y, textPaint);} else if (angle * i > Math.PI / 2 && angle * i <= Math.PI) {float dis = textPaint.measureText(titles[i]);canvas.drawText(titles[i], x - dis, y, textPaint);} else if (angle * i >= Math.PI && angle * i < 3 * Math.PI / 2) {float dis = textPaint.measureText(titles[i]);canvas.drawText(titles[i], x - dis, y, textPaint);}}}

到这里就完成了蜘蛛网图的自定义View绘制。

自定义View -- 蜘蛛网图相关推荐

  1. android自定义u形线,Android实战之自定义View折线图

    如果你对自定义View还不是很了解,那么这篇文章将从实战的角度带你一步一步的编写出一个符合规范的自定义View. 需求:假设有一个病人,他不定时的将自己的血压值录入到我们的客户端,而我们要做的就是将他 ...

  2. 自定义view走势图(二、加入动画和触摸事件)

    很早就想来完善之前写的走势图(一)了,结果两个月感觉天天都在忙,无脑写代码,还偶尔通宵,尼玛啊,一脸要死的样子,现在总算有点时间了~~~~ 这篇是在第一篇的基础上进行的完善和改进,主要就是加入了动画和 ...

  3. 自定义view走势图(三、贝塞尔曲线)

    在开发中,对于走势图和统计图,会有用平滑的曲线来进行展示的需求,我首先想到的就是贝塞尔曲线.那么贝塞尔曲线是啥呢,贴上两张图多看一会就明白了 图一     图二 上面图一是二阶贝塞尔曲线,图二是三阶贝 ...

  4. Android自定义View实现三角到八角的属性分布图-雷达图(蜘蛛网图)

    Android自定义View实现三角到八角的属性分布图-雷达图(蜘蛛网图) 前言 自定义View的关键点 绘制多边形 结尾 前言 刚开始学习自定义view,简单完成了一个属性分布器,可以实现三条到八条 ...

  5. 自定义蜘蛛网图 NetView

    概述 写论文忙里偷闲写了一个蜘蛛网图的自定义view,支持多重属性 有图才能有真相,下面先上图 主要支持网格颜色.tag文本.覆盖区域颜色.透明度的属性改变,具体使用可以参见我的githubgithu ...

  6. 【Android】自定义蜘蛛网图

    步骤 步骤一:新建一个类继承自view 步骤二:重写onDraw()函数,需要绘制网格图,中位线以及数据的填充方法 简单思路:onDraw函数中,我们写了三个新的函数,分别用来绘制网格,中位线和数据 ...

  7. Android自定义View 多边形能力分析控件,雷达图(蛛网)动态实现

    自定义View实现雷达图还是挺简单的,它能让使用让使用者能一目了然的了解各项指标的变动情形以及好坏趋势.使用得最多的便是Path路径,很适合初学者用来练习. 效果图如下: 下面是实体类的属性: pub ...

  8. Android 自定义雷达图(蜘蛛网图)

    这次自定义实现雷达图,它可以用在分析某些内容所占的比例,比较直观地突出某些数据,比如可以用在游戏玩家的各项能力的分析上,那么它的各项指标就比较明显地看出来了.效果图如下: 看完这幅图大家就清楚要实现的 ...

  9. Android 自定义View -- 简约的折线图

    转载请注明出处:http://write.blog.csdn.net/postedit/50434634 接上篇 Android 圆形百分比(进度条) 自定义view 昨天分手了,不开心,来练练自定义 ...

最新文章

  1. php适配器模式应用,什么是适配器模式,它有哪些应用场景
  2. C# 程序员最常犯的 10 个错误
  3. 糟糕!服务器被植入挖矿木马,CPU 飙升200%。。。
  4. kaggle入门项目:Titanic存亡预测(三)数据可视化与统计分析
  5. python试卷河南理工大学万方科技学院_河南理工大学万方科技学院
  6. 【Deep Learning 五】课程二(mproving Deep Neural Networks),第一周(Setting up your Machine Learning Applicat)答案
  7. web 前端routine
  8. Atitit 法学处罚方式模式 目录 1. 申诫罚、财产罚和能力罚 1 1.1. 申诫罚 (警告和通报批评 ) 1 1.2. 财产罚是指使被处罚人的财产权利和利益受到损害的行政处罚。 2 1.2
  9. word 2007为不同页插入不同页眉页脚
  10. MySQL增加字段SQL语句
  11. 使用华为modelarts进行车辆识别
  12. 医院计算机,医院计算机
  13. python gif转jpg_PIL-将GIF帧转换为JPG
  14. 51单片机最小系统板制作
  15. 真正影响孩子一生的不是中高考,而是四、五年级!(深度好文)方格教育
  16. idea、webstorm使用过程出现问题
  17. 蓝牙鼠标windows linux,解决Ubuntu 18.04与Windows 10双系统蓝牙鼠标连接的问题
  18. python 语音识别培训使用Python和Keras创建简单语音识别引擎
  19. python xlwt表格写入操作
  20. ubuntu下查看opencv安装路径以及版本号

热门文章

  1. UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xbd in position 14: illegal multibyte sequence
  2. 杜克大学计算机科学博士,杜克大学计算机科学哲学博士研究生入学条件
  3. Abp.Zero 手机号免密登录验证与号码绑定功能的实现(二):改造Abp默认实现
  4. 【转】全屋WiFi覆盖无死角,Mesh组网是最佳选择!领势MR9000X组网实测
  5. 阿里云服务器ECS如何进行远程连接?
  6. MySQL中的事务回滚机制
  7. Mac Docker入门安装使用
  8. Unity发布WebGL注意事项以及移动端打开webgl网页
  9. CDA数据分析浙江师范大学 第二期“正阳旅游大数据创新创业班”项目报告会顺利开启
  10. 计算机配置怎么开启,ipv6怎么设置? ipv6的开启方法