android 圆环温度控件,Android自定义View分享——一个圆形温度显示器

写在前面

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

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

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

本文适合什么样的人

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

效果展示

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

456d4697325fcfec4b21ad1b7a64194c.gif

简介如下:

1. 控件中间文字显示当前温度,圆环边上两个文字分别显示最高温、最低温。

2. 圆环的背景是蓝色,红色部分显示的是所设置的温度范围。

3. 由于只是一个示例,为了方便(偷懒),所接受的温度范围设置为0℃~60℃,60℃平分360角度,提这一点是方便你理解部分数学运算。

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

设计思路

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

1. 弧线动态变化完成之前:这时我们要做的是画个蓝色圆形作为背景,然后根据温度的上下限,绘制弧线,而且还要不断变化扫描过的角度,不断重绘,以此实现变化效果。

2. 弧线动态变化完成之后:此时主体已经完成,动态效果也实现了,只要根据温度的上下限,在对应的位置写上最高温和最低温就行了。

下“笔”之前,再提一点

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

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()方法,就是为了简化这些操作。我承诺(装逼时间):绝对不用三角函数(其实给我用也忘了怎么用了),只要使用很简单的计算就能绘制文字。

1. 首先,我们根据最低温来计算文字对应角度,然后将坐标系旋转对应角度,让文字的位置处在y轴上面。

2. 沿着y轴移动坐标系,将坐标系原点移动到绘制文字的地方去。

3. 将坐标系反方向旋转第一步转的角度,此时坐标系的原点就在文字该出现的地方,而且坐标系已经摆正了。

4. 绘制文字。

5. 将坐标系还原回去。

图片如下:

61cf194c65c80c1bf2a4f1ffa2aef5e1.png

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

//重置degreeProgress

degreeProgress = 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();

下期预告:

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值