900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Android自定义View分享——一个圆形温度显示器

Android自定义View分享——一个圆形温度显示器

时间:2023-07-10 09:39:39

相关推荐

Android自定义View分享——一个圆形温度显示器

写在前面

笔者近来在学习Android自定义View,收集了一些不算复杂但又“长得”还可以的自定义View效果实现,之前分享过一个水平的进度条,如果你有兴趣的话可以看看:

Android自定义View分享——一个水平的进度条

今天来分享第二个效果:一个圆形温度显示器

本文适合什么样的人

如果你接触自定义View不久,看懂了View绘制基本流程,知道onMeasured()、onLayout()、onDraw(),知道Paint、Canvas类及其API很强大但没用过,正准备大显身手来几个自定义View却又不知道该“画”一个怎么样自定义View比较合适,苦恼于网上各种开源项目太高端,看不懂,那么本文及后续的博客很适合你,来让我们一起拿起铅笔(Paint)、白纸(Canvas)来当一回艺术家呗。

效果展示

今天我们要画一个这样子的东西

简介如下:

控件中间文字显示当前温度,圆环边上两个文字分别显示最高温、最低温。圆环的背景是蓝色,红色部分显示的是所设置的温度范围。由于只是一个示例,为了方便(偷懒),所接受的温度范围设置为0℃~60℃,60℃平分360角度,提这一点是方便你理解部分数学运算。

基本介绍差不多了,来让我们当一回码农界的梵高吧。

设计思路

根据我们前面的简介,主体思路分为两个部分:

弧线动态变化完成之前:这时我们要做的是画个蓝色圆形作为背景,然后根据温度的上下限,绘制弧线,而且还要不断变化扫描过的角度,不断重绘,以此实现变化效果。弧线动态变化完成之后:此时主体已经完成,动态效果也实现了,只要根据温度的上下限,在对应的位置写上最高温和最低温就行了。

下“笔”之前,再提一点

按照笔者所提出的设计思路,你大概会用到如下一些方法,也许你可以在绘制之前稍微了解一下它们,这样能让你更好地阅读绘制过程。当然,你也可以直接跳过,你也可以“边画边学”。

canvas.translate()、canvas.rotate()、canvas.save()、canvas.restore():对于圆形及弧线的绘制而言,通过translate()方法将坐标系移动到控件中间可以简化某些数学计算,对于要在圆的边上写字或者绘制其他东西,灵活运用rotate()、save()、restore()方法,可以简化一些计算。canvas.drawCircle(float, float, float, Paint):绘制圆形的API,前面两个参数表示圆心位置,第三个表示半径的长度,第四个是画笔对象。drawArc(RectF, float, float, boolean, Paint):绘制弧线的API,关于canvas绘制弧线具体逻辑,我建议你还是稍微搜索一下,我在这里不展开来讲了。canvas.drawText(String, float, float, Paint):绘制文字的API,第一个参数是文本,第二个和第三个是文本绘制在什么位置,第四个参数是画笔,canvas的文本绘制具体位置计算也很繁琐,但是其实并不复杂(并不算难),它是一个单独的知识点,不在这里细说了,你可以在你可以很轻易地在搜索引擎上面找到。

从艺术回归农田(从草稿纸到写代码)

根据我们前面的思路,现在详细说明一下弧线变化完成前后编程步骤。

弧线动态变化完成之前

将坐标系原点移到控件中间。绘制一个蓝色圆形作为背景。根据最高温最低温,绘制一个红色弧线。绘制当前温度说对应的文字。记录当前扫过角度,角度增加,重绘。

代码片段如下所示:

int halfWidth = getMeasuredWidth()/2;int halfHeight = getMeasuredHeight()/2;//绘制原理:先画圆形,再画弧线,不断变化弧线扫过角度,以此实现温度动态变化效果canvas.translate(halfWidth, halfHeight);//画圆形canvas.drawCircle(0, 0, halfWidth-circleWidth/2, circlePaint);//画弧线arcRectF.set(circleWidth /2-halfWidth, circleWidth /2-halfHeight, halfWidth- circleWidth /2, halfHeight- circleWidth /2);//温度的有效范围是0~60℃,360°对应60℃,每一摄氏度占用六角度canvas.drawArc(arcRectF, minTemperature*6-90, degreeProgress, false, arcPaint);//绘制中间所显示的当前温度canvas.drawText(nowTemperature+"℃", 0, nowTemperatureTextY, nowTemperaturePaint);//"degreeProgress"的不断变化是动画效果关键degreeProgress++;if(degreeProgress<=(maxTemperature-minTemperature)*6) {invalidate();}

弧线动态变化完成之后

这时我们要做的就是在温度值上下限对应的地方,绘制文字。你可以通过“硬编码”,通过半径利用三角函数计算文字坐标。然而我们刚才提到canvas的rotate()、save()、restore()方法,就是为了简化这些操作。我承诺(装逼时间):绝对不用三角函数(其实给我用也忘了怎么用了),只要使用很简单的计算就能绘制文字。

首先,我们根据最低温来计算文字对应角度,然后将坐标系旋转对应角度,让文字的位置处在y轴上面。沿着y轴移动坐标系,将坐标系原点移动到绘制文字的地方去。将坐标系反方向旋转第一步转的角度,此时坐标系的原点就在文字该出现的地方,而且坐标系已经摆正了。绘制文字。将坐标系还原回去。

图片如下:

代码片段,改代码片段包含了两个位置文字绘制。

//重置degreeProgressdegreeProgress = 0;//绘制最高温最低温文字canvas.save();float rotateDegree = 180+minTemperature*6;canvas.rotate(rotateDegree);canvas.translate(0, halfWidth-circleWidth-10);canvas.rotate(-rotateDegree);canvas.drawText(minTemperature+"℃", 0, maxAndMinTemperatureTextY, maxAndMinTemperaturePaint);canvas.restore();canvas.save();rotateDegree = 180+maxTemperature*6;canvas.rotate(rotateDegree);canvas.translate(0, halfWidth-circleWidth-10);canvas.rotate(-rotateDegree);canvas.drawText(maxTemperature+"℃", 0, maxAndMinTemperatureTextY, maxAndMinTemperaturePaint);canvas.restore();canvas.save();

项目源码:

/kingfarou/SimpleCustomView

下期预告:

下篇文章,我将分享一个仿照微信朋友圈合并图片的效果,像这样子:

对于微信朋友圈,当某一条信息里面有多张图,你会在浏览列表里看到他们缩略图的合并。这个效果有可能是后台做了图片合并,发到客户端就只是一张合并后的图片,但是如果后台不帮你做合并,你自己该怎么做呢?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。