大家好,可能今年换了公司过得比较安逸,自己的心情也不算太好,所以一段时间都没很好的学习和更新文章。自从最近看了扔物线HenCoder的文章之后,自己感觉自己对很多自定义View和动画的知识都不太懂,甚至在平时的开发极少用到,所以自己想好好学习这一块的知识。之前无意中在公众号上看到一个仿英雄联盟的的七边形战力图,自己发现,平时我看的好几个app都有这样的多边形战力图,所以觉得可以自己做一个大众版的出来,适配各个关于多边形战力图的自定义View。下面我们看看效果图:
大家看看我写的代码就知道了:
用一个正六边形举例,假设说它每个角到坐标原点为半径X,那么我们用数学的原理XcosA就能得出得出B点的X轴坐标,XsinA能得出B点的Y轴坐标,由此我们看出来B(XcosA,XsinA),至于∠A的度数怎么来的就更简单了,正n边形360°/ n,即 2π/n 就能得到一个角是多少度的了。那很自然而然的,我们用一个for循环就可以得出六边形所有的坐标点
for (i in 0..count - 1) {
//每个坐标点
(radius * cos(2 * Math.PI / count * i)).toFloat(), (radius * sin(2 * Math.PI / count * i)).toFloat())
}
以上就是多边形战力图的数学原理,应该很简单吧。其实很多自定义View也是一样,只要懂了原理,很多东西很自然而然很简单的就能写出来。生活上很多事情也是一样,没做之前什么事情都想着自己做不好就放弃了,但是自己尝试了发现原来这个事情原来那么简单,我每次写自定义View总有这个感慨。
不吹什么了,确实毕业一年多工作两年最近感慨有点。好了,下面我们来看看代码我是怎么一步步实现的吧。在实现代码之前,我先说这个View我是用kotlin写的,最近也慢慢用kotlin写代码写项目。一开始确实很不习惯,速度很慢,但是我觉得我总会熟能生巧的吧,所以贵在坚持嘛。 下面我们以懂球帝的六边形战力图为例一步步画出想要的效果吧:
一、首先我们需要画出一个多边形,和嵌套的多个多边形。
代码很简单,我们看看红色框里面的代码就是最核心的部分,一个for循环,刚刚讲原理的时候也说过。那下面详细分析一下,当i=0的时候,我们把path移动到我们的第一个点上,
path.moveTo((radius * cos(2 * Math.PI / count * i - Math.PI / 2)).toFloat(), (radius * sin(2 * Math.PI / count * i - Math.PI / 2)).toFloat())
当i>0的时候,我们就需要把这些点用路径直线连起来了,所以用的是lineTo()
path.lineTo((radius * cos(2 * Math.PI / count * i - Math.PI / 2)).toFloat(), (radius * sin(2 * Math.PI / count * i - Math.PI / 2)).toFloat())
有人会问为什么角度最后需要减去π / 2,那是因为我们需要把六边形旋转一下,视觉效果更好。
二、画六边形的中心到每个角的角边:
有人注意到了吗,我们在第一个for循环的时候加了一句代码:
//把相应的点保存到pointList中
points.add(PointF(radius * cos(2 * Math.PI / count * i - Math.PI / 2).toFloat(), radius * sin(2 * Math.PI / count * i - Math.PI / 2).toFloat()))
这句代码就是把我们所要画的六边形的六个点的坐标保存了下来,为方便我们之后用,而且下面很多地方都用到了,你看,这里就用到了。
三、画出字体
四、画出分数区域及设置相关属性
1.我们要设置分数区域的一些属性,另它更好看一点:
下面讲讲做这个自定义View在kotlin上遇到的一些小问题:
1.构造函数的编写跟java有区别:
2.kotlin的小坑:
谁都知道,kotlin是不需要在代码中初始化xml控件的,这一点用过的人都会觉得很方便,但是在这里我踩了一个小坑,看下图:
dongqiudiPolygonView = findViewById(R.id.dongqiudiPolygonView)
最近在简书感觉渐渐没人看了,所以第一次在掘金发布文章,如果大家想看我的文章,我可以把那边的文章迁移到这边来。 我的简书