TemperatureView: 这是一个自定义 View ,用来显示温度的变化过程。前段时间公司要做一个实时监测机房温度的应用,现在把这个温度变化的 View 拿出来,自己对自定义 View 这方面的应用还不是很熟悉,这里也算是对自己工作的一个小总结。
二话不说,先上个效果图:
当然,正常室温变化是没有这么快的,再来张截图:
下面来说说这个过程,首先可以将它分为几个部分,分别为:
1、整个背景圆(可有可无)
2、进度弧(分为三段,颜色分别为绿黄红)
3、进度弧上的文字(正常,预警,警告)
4、刻度弧(紧靠着进度弧内侧的黑色弧)
5、刻度
6、中间的圆
7、指针
8、当前温度
那些自定义属性就不多说了,下面直接是绘制的过程(在此之前需要对绘制过程所用到的相关类有一定的了解)。
背景圆(可有可无,全凭个人喜欢)
1 | /** |
mSize:是控件的大小,mSize /2-dp2px(1):是让这个背景圆和控件有点距离。
进度弧
1 | /** |
整个进度弧是从150度的位置开始到30度为止,也就是说整个进度弧所占的角度为240度。将它分为40份(也就是最高40度的意思),所以刚好每份是6度。
给出的效果图中进度弧是绿黄红的,在这里的绘制顺序却是绿红黄,这是因为我想要将进度弧的两端(绿和红)设置为圆角,而黄色与绿色和红色的衔接处为直角。如果在这里的 Paint 只是设置为 Paint.Cap.ROUND ,那么中间黄色部分和红绿的衔接处也是圆角的;如果按照绿黄红的顺序来绘制,那么黄色和红色衔接处是圆角的,而绿色和黄色衔接处是直角的。其实很简单,如果理解不了就动手试一下,保证瞬间明了。
进度弧上的文字(正常,预警,警告)
1 | /** |
如果直接 drawText ,那么绘制的文字是水平的,想要把文字绘制在进度弧上,得先旋转一定的角度。拿绿色这段弧来说:它占了120度,所以中间位置是60度,那么就需要旋转60度了。
有一点要注意的是,绿色这段弧在左边,所以要逆时针旋转60度(旋转角度为负数是逆时针,正数是顺时针)。第二段弧上的文字为什么旋转了90度呢?它只需要旋转30度就可以了啊?那是因为第一段弧时旋转了-60度(逆时针),而第二段是从第一段的基础上旋转过来的,所以需要顺时针旋转90度。
刻度弧(紧靠着进度弧内侧的黑色弧)
1 | /** |
这里只是简单的画条弧,只要注意半径的把握就可以了。
刻度
1 | // 旋转的角度 |
这里只给出了右半部分的刻度,左半部分类似。绘制时先是旋转角度(一共240度,分成40份,每次旋转6度),然后再画直线;画直线时还要判断如果是5的倍数,就画长一点,并且标上刻度值,就是那些0,5,10,15…
这里是右半部分,所以刻度值是从20开始,总共是20个刻度。最后要注意画布回正
canvas.rotate(-mAngle * mTikeCount/2 - 6, 0, 0) 。
中间的圆
1 | /** |
这个圆是为了凸显接下来的指针更好看一些,这个圆的半径就自行选择咯。
指针
1 | /** |
其实指针部分可以一次性绘制完,但是为了看起来有点立体感,就将它分为左右两部分,但是都是类似的。
就拿左半部分来说:首先将画笔移动到中心圆的边缘( leftPointerPath.moveTo(pointRadius/2, 0) ),然后来个弧度是让指针的根部为弧形的,接下来是指针的长度(长度=刻度弧的半径(scaleArcRadius) - 长刻度的长度(mLongTikeHeight) - 刻度值与刻度的间隔(dp2px(15)) - 尾部与刻度值的间隔(dp2px(OFFSET))),最后再将它们连接起来。
指针上的圆意思是指针根部灰色的小圆,这样看起来指针的根部是有个小洞的。
由于之前对这些 Path 的操作不怎么熟悉,所以在这里花的时间较多,而且指针这部分所占的篇幅也是蛮大的,因为难度也比较大嘛。
有兴趣的可以来这学习巩固下,这个系列都很给力:安卓自定义 View 进阶 - Path 基础
当前温度
1 | /** |
这部分是表盘上显示的当前温度,首先是绘制“当前温度” 这四个字,然后在下方绘制具体的温度值,注意好文字的位置就可以了,没什么难的。
到这里绘制就结束了,整个表盘也就出来了。其实自定义一个 View 最重要的是把它拆分为几个部分,然后再一部分一部分的绘制出来,至于其中的某些计算部分就得靠自己的细心了,但是多试几次还是可以出来的。
篇幅有限,只是拿出一些关键的代码,有兴趣可以来这看看源码,随便 Star 、Fork Github:https://github.com/ljuns/TemperatureView