Android仿华为天气绘制刻度盘


效果图


 
可以看到这个自定义控件结合了颜色渐变、动态绘制刻度、动态水球效果。接下来我们就来看看这个效果是如何一步一步实现的。

开始自定义控件


和很多自定义控件方式一样需要去基础某种View或者某种ViewGroup 
我这里选择的是View,如下所示:

其中构造方法用来布局中使用。 
onMeasure()方法用来测量和限定view大小 
onDraw()方法用来进行具体的绘制功能 
如想详细了解请点击: 
构造方法 
onMeasure() 
MeasureSpec 
onDraw() 
了解以上方法功能后,我们在来看看如何具体使用吧

1使用onMeasure()方法将View限制为一个正方形

只有确定了一个矩形才能够去画椭圆,如果这个矩形是正方形,椭圆也就随之变成了圆形。

分别通过MeasureSpec取得用户设置的宽和高,然后取出最小值,设置给我们的view,这样我们就做好了一个矩形 
现在使用在布局中:

 


父布局背景为蓝色背景,控件背景为粉色背景,而且设置的宽高不同,但是控件的显示效果还是一个正方形,而且以小值为准。我们的onMeasure()生效了 
接下来就是如何在确定一个圆形区域了

2onDraw()绘制圆形区域

绘制之前我们需要对Android中的坐标系有个了解 

 


我们都知道手机屏幕左上角为坐标原点,往右为X正轴,往下为Y正轴。其实手机页面就是activity的展示界面,也是一个View。那可不可以说所有的View在绘制图形的时候都有自己的这么一个坐标系呢(个人想法。。。) 
也就是所每个View都有自己的一个坐标系,比如现在的自定义View: 


 


现在我们需要在我们自定义的view中绘制一个圆弧,那么这个圆弧的半径就是我们自定义view的长度的一半,即: 
radius=len/2; 
那么圆心的坐标刚好是(radius,radius)

接下来开始绘制



介绍一下绘制圆弧的方法:

  • 参数一oval是一个RectF对象为一个矩形

  • 参数二startAngle为圆弧的起始角度

  • 参数三sweepAngle为圆弧的经过角度(扫过角度)

  • 参数四useCenter为圆弧是一个boolean值,为true时画的是圆弧,为false时画的是割弧

  • 参数五paint为一个画笔对象 
    也就是说只要确定了一个矩形,在确定他起始和经过的角度就能够画出一个圆弧(这点大家可以用画板测试)

接下来就是初始化这些参数

初始化矩形

画矩形需要确定左上角和右下角的坐标(通过画板可以测试),通过上面的分析坐标原点就是我们view的左上角,右下角的坐标当然就是len了。

接下来就是初始化起始和经过角度

需要搞清楚往下为Y轴正轴,刚好和上学时候学的相反,也就是说90度在下方,-90度在上方

初始化画笔


到这里真不容易呀,然而发现只画个圆弧没用呀,我要的是刻度线呀,canvas里面又没用给我们提供画刻度线的方法,这个时候就需要我们自己去写一个画刻度线的方法了。 
通过观察图片我们可以看出,所有的线都是从圆弧上的点为起点向某个方向画一条直线,那么该如何确定这两个点呢,需要我们做两件事:

移动坐标系

我们自己写了一个绘制刻度线的方法并在onDraw()方法中调用。移动坐标系之前需要保存之前的canvas状态,然后X和Y轴分别移动圆弧半径的距离,如下图: 


canvas.translate(radius,radius);方法移动的是坐标系(通过实际效果和查资料所得) 
canvas.save()和canvas.restore()要成对出现,就好像流用完要关闭一样。

第一件事情完成后,开始第二件事情,旋转坐标系

只通过移动坐标系,仍然很难确定圆弧点上的坐标,和另外一点的坐标, 
如果这两个点都在坐标轴上该多好呀,下面实现:

画刻度线的方法了增加了一个旋转30度的代码,旋转后的坐标系应该怎么样呢; 

 
因为起始点和90度相差30,旋转之后,起始点刚好落在了Y轴上,那么这个点的坐标就很好确定了吧,没错就是(0,radius);如果我们在Y轴上在找一点不就可以画出一条刻度线了吗,那么它的坐标是多少呢?对,应该是(0,radius-y),因为我们要往内部化刻度线,因此是减去一个值,赶快去试试吧,代码如下:

根据得到的两个点的坐标,画出来一条白线,如图: 

当然这些点都是移动后的坐标系在旋转30度得到的,这里画好了一条线,如果画多条呢,还是刚才的思路每次都让它旋转一个小角度然后画条直线不就好了吗,那么旋转多少度呢,比如这里:总共扫过的角度sweepAngle=300;需要100条刻度,那么每次需要旋转的角度rotateAngle=sweepAngle/100,具体代码如下:

100个刻度,需要101次循环画线(请看你的手表),画完线就旋转。依次循环,如图 


经过这么久的时间总于完成了刻度盘了,接下来就是去确定不同角度显示什么样的颜色,首选我们需要确定要绘制的范围targetAngle:

绘制有色部分

我们需要不断的去记录绘制过的有效部分,之外的部分画白色。 

根据角度的比例,颜色渐变

需要计算出已经绘制过的角度占总角度(300)的比例

只是在绘制有色部分的时候,利用三元素来实现渐变。所占比例越低红色值越大,反正绿色值越大。 


实现动态显示

先想一下它的运动情况,分为前进状态和后退状态,如果正在运动(一次完整的后退和前进没用结束),就不能开始下次运动,需要两个参数,state和isRunning

利用时间任务,每个30毫秒去执行一次run方法,每次都重新绘制图片,然后在activity中调用此方法

看到这里了,相信你对坐标系和角度动态变化,以及刻度盘的绘制有了个很好的认识,多多验证会有助于理解。

接下来要实现背景动态渐变

想想咱们的view中哪里用了渐变呢?对,在绘制有色部分的时候,如果我们能将颜色渐变的值不断的传到activity中该多好呀,下面就要用接口传值实现这一功能了:

  • 首选在自定义View中声明一个内部接口:



我们在自定义View中声明一个内部接口,并声明一个全局接口对象,提供一个set方法 
接口内有个方法用来获取颜色值 
接下来就是在合适的地方调用这个方法,那么哪里呢,就是我们绘制颜色刻度时调用:

我们在绘制的时候实现了接口回调,接下来去activity中实现接口

给父布局一个id,然后实例化。给我们的自定义控件设置一个角度颜色变化监听,从而拿到回调中传过来的值,然后借助Color对象将RGB值转为int值,再设置给父布局背景,这里背景稍稍透明一些。效果图: 

到了这里是不是感觉炫酷了不少呢,其实功能已经实现的差不多了,接下来就是去绘制里面的内容吧

绘制文字

当然不去绘制文字也是可以的,你可以直接在布局中添加textview等。好话不多说,先分析一下绘制的过程吧,在刻度盘的内部有一个小圆,然后这些文字就在小圆内,绘制小圆只需要让它的半径小点就OK了。

这里将之前渐变的red和green提为全局变量,先绘制一个小圆,画笔颜色渐变。然后绘制文字分数score需要通过计算的到

在时间任务中,每次绘制之前计算得到分数,然后在右上方画一个固定值分,再在下方一个固定内容点击优化(这个时候的坐标已经回到最初的模样) 


到此为止功能已经写的差不多了,还有一个水波加速球效果,下篇博客中写吧。 
最后对于原理底层方面,我也有待学习,有错的地方欢迎指正,谢谢。项目已经上传到github 

github点击下载 :https://github.com/YISHUIH/HuaWeiWeatherView



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,427评论 25 707
  • 今天要说的是“活在未来”这个概念,作者曾经说过,如果一个人的脑子里没有某个概念的话,就不会去思考相关的问题。那么既...
    方知方行阅读 136评论 0 0
  • 今天是星期天,天气晴朗,风和日丽.妈妈的朋友唐文娟阿姨带着她的新宠—一只可爱的小巴哥犬,来到我们楼下找我们玩。 小...
    卞琪浩一阅读 147评论 0 1
  • 明明是那么相爱,可最后还是散了。 我们有过约定,要走很长的路,爬很深的山,看很蓝的海。 可惜到最后才发现,彼此已是...
    tc大叔阅读 719评论 2 3