阅读本文大概需要 6.6 分钟。
这是我司同事的一篇文章,介绍了我们项目中实际开发中用到的一个自定义View组件,希望对你们能有借鉴作用,可以点击「阅读原文」跳转到作者原博客。
1
背景
项目中之前用的纵向滚轮用于选择身高体重之类的需求,新版设计要求用横向刻度尺控件来实现,效果图,上面的字不在刻度尺范围内,是一个TextView。
自定义控件对于 Android 开发者来说是必备技能,这篇文章就不讲自定义 View 的基础知识了,主要谈谈绘制逻辑。
2
实现
遵循自定义 View 的开发流程,onMeasure() –> onSizeChanged() –> onLayout() –> onDraw()。由于我们要自定义的是 View 而不是 ViewGroup ,所以 onLayout() 就不用实现了。
3
onMeasure() 测量
onMeasure() 用于测量 View 的大小,View 的大小不仅由自身决定,同时也受父控件的影响,为了我们的控件能更好的适应各种情况,一般会自己进行测量。刻度尺 View 左右是满屏的,偷个懒宽度就不适配了,只做高度测试就好了。高度包括长刻度的高度,加上字和底部间距
4
onDraw() 绘制
绘制做了三件事情:
绘制背景色
绘制指示器
绘制刻度
只看下怎么画刻度,难点在于怎么确定刻度的坐标。首先高度的坐标是一样的,刻度指示器是在屏幕正中,指示某个值,那么该刻度值的x坐标就是确定的。根据这个值去画其他坐标,包括长刻度和短刻度。
首先要确定每个长刻度(和短刻度,如果有的话)的坐标宽度和单位,确定基础单位和基础单位宽度(如果有短刻度以短刻度为基础单位)。那么
第i个刻度x坐标 = 中间刻度x坐标 + i * 基础单位宽度
其中i的取值范围在正负屏幕可绘制多少个基础单位,第0位就是屏幕正中的刻度值。以该值为基础一次画出可以在屏幕中显示的剩余刻度,如果是长刻度单位的整数倍就画长刻度,刻度值只在长刻度下画。
这样就有一个问题,正中刻度值必须是可以整除基础单位,比如,长刻度 = 1,中间两个短刻度,这样基础单位值就是0.5,currentValue = 0.3,那么下一个值就是0.8,但是这样显示并不是我们想要的,我们想要0、0.5、1、1.5这样的值。所以就是在初始化的时候格式化这些值,使得所有可显示的值都可以整除基础单位值,也就是余数为0。
由于使用float计算,所以要用到float精确计算,否则取余操作会出现不等于0的误差导致画不出长刻度。
5
处理滑动操作
滑动处理比较简单,以初始化为基础,每次move操作累加x坐标,以此值绘制偏移量,停止滑动时以基础单位宽度为基准四舍五入,开始动画滑动到相应的刻度值上。
主要方法:
关于刻度的单位,需要给出长刻度单位和中间的短刻度个数,这样中间的短刻度单位就确定了,所以理论上不管中间有几个短刻度计算都是一样的。我在里面封装了三个常用的,2、5、10三种。
支持的 styleable
代码在这里:
https://gist.github.com/w4lle/2f676f0f2005f6a24ca6c122b7e214b4
最后,实现的效果比较单一,主要是面向产品方面的需求,没有做太多的扩展,有时间再完善下。
之前的这篇文章,为了感谢大家对我的生日祝福,我特地为大家准备了福利,在不知道有福利的情况下,你们的对我的赞赏绝对是真心的,我良心张也不是虚的,来看下都有哪些幸运儿:
「李济洲」、「Sure」、「Eason Cui」、「潇洒哥。」、「飞」、「举例说明」、「静女其姝」、「white」、「liufeng#」、「存在」、「warm」、「走着」、「小河马」、「( ̄o ̄) . z Z 」、「楷」、「尹逸良」、「邱拓先」、「a邱振环」、「Agoni」、「落叶」、「一半」、「Baron」、「StormMa」
妈蛋,我也不知道剩下的礼物还够不够,礼物是 100offer 的 Cherry 鼠标垫外带一个小U型颈枕,不够的话我给你发红包代替。另外,快递费自费,还请谅解。至于为什么这些人能中奖,想必他们自己会知道!
最后,有多少人还记得明天是丧心病狂的高考日?想想他们,在想想现在的自己不用高考简直幸福死了。如果现在我们能拿出当年高中十分之一的努力,那还有什么学不会?所以,每当你学不下去的时候,想想自己,当初也是那么的拼命努力,现在为什么就不可以了?
对了,这是我明天的准考证,大家预祝我高考成功吧!