自定义View之酷炫刻度尺

1,111 阅读3分钟

最近收到了一个自定义刻度尺的需求,中间红线不动,可以左右滑动刻度尺选择数值,支持自动吸附到刻度上,以保证每次滑动后选择的都是整数。下面笔者以最初的想法开始慢慢介绍这个控件,一步一步将其实现。

1.如何实现刻度被半圆截断效果

我们可以看到,背景并不是最初的长方形而是左右一边一个半圆衔接起来的。而且里面的内容都分布在这个背景中,如果超出就需要将其截断。

这里是使用到画布的裁切功能,首先利用path来画出整个轮廓,最后调用canvas.clipPath(mPath)实现将当前画布根据当前path进行裁切。


2.如何实现背景的内阴影效果

这个控件是有内阴影的,左右上角比较明显。但是这个阴影如果要画出来是很费劲的,需要分段来实现,而且要画多次。这里就偷了个懒,直接将设计书上面的切图下载了下来,然后将图片通过canvas.drawBitmap()的方式画到了控件上,画完感觉事半功倍,还好不用适配平板,并没有出现问题,娃哈哈,偷偷开心一下。这里画的时候需要注意图片放置的位置还有图片大小,有margin的话需要平移。


3.如何控制滑动的左右边界

由于控件支持手势滑动,不可避免的问题就是左右边界的判断。可以记录上次滑动的距离,然后本次加上上次的距离时判断是否会超过边界,如果会那么只滑动到边界的距离,否则直接滑动目前接触点和上次停止位置的距离。注意滑完需要调用invalidate()方法来重绘控件。


4.如何实现自动吸附到刻度的效果

如果不做任何处理,那么将会出现滑动到某两个刻度中间的问题,体验并不好。为了解决这问题,加入了一个缓冲量变量mMoveBufferX。从上图中可以看到,每次滑动后都会记录下滑动的缓冲值,并且会根据缓冲量计算本次最近的刻度,滑动到该刻度,并且缓冲量减掉该刻度值,剩下的缓冲量将在下次滑动时继续参与计算。


5.如何处理刻度尺的随时可配置初始位置

控件中控件初始位置是可变的,也就是说刻度尺需要移动到其值的相应位置。这里做法是计算出当前值应该占控件中具体哪个小刻度,然后计算偏移量mOriginOffset,这里减去半个屏幕宽度,是为了让滑动到边界时,边界正好在屏幕中间,而不是最左边,提升一下用户体验。



6.如何使用自定义字体

该控件中的标数为自定义字体,设计师说的,呵呵我并不觉得哪里好看了。包括目前页面上很多都是自定义的Lato字体,没办法当然是搞定它啊。使用自定义字体一般有2种方式。

第一种是将相应的字体文件放到项目中的res/font文件夹下,然后在TextView的属性中通过android:fontFamily="XXXX"的方式来调用。


第二种是将字体文件放到asset目录,然后通过Typeface.createFromAsset方法读取asset目录下的字体文件,最后通过setTypeface方法将字体设置到view中或者paint中进行绘制。


这里需要注意,其实在API 26以后Paint也支持从font资源文件夹下面加载字体文件,但是也仅支持26以后,所以在自定义View中还是老老实实地使用setTypeface方法吧。但是在给TextView设置时可以使用从font加载的方式,可避免多封装一层自定义TextView。

 demo地址:github.com/dongrong-fu…