自定义观点实现跟随手指滚动的刻度尺,实现了类似SeekBar的滑动选中效果。项目地址,欢迎明星!
界面图:
功能:
-
<李>通过设置最小值跟最大值的范围,以及偏移值.View将根据这些数据去计算出需要几个小刻度和几个长刻度,和每个长刻度上面显示的数值。李>
<李>指针可以随意的定制。李>
<李>当滑动停止后,刻度尺会根据四舍五入将距离指针最近的长刻度滑动到指针的位置。李>
<李>支持范围越界回弹。李>
<李>支持设置默认值。李>
先扯一下,再看别人写的控件的时候总有一种一脸懵逼的感觉,好多凌乱的变量和一大堆的计算逻辑都不知道干嘛用的。比如:PullToRefreshLayout。除非自己按着整体的设计流程写一遍,一步步的写,等出了错误你就明白那些操作的价值。结合之前读第三方控件的经验,写这个刻度尺控件的时候就一步步的去完成,从简单的绘制,到点击事件,再到滑动舞,最后滑动结束更正滑动位置。每一步遇到的问题都记录下来,之后再补全解决方法,这就是成长。
<强> 1。绘制刻度强>
这里省略了onMeasure,这里的需求只是计算一下高度就好了,接着看onDraw方法:
私人空间drawRuler(帆布画布){ mTextIndex=0; for (int指数=0;指数& lt;=mRulerHelper.getCounts ();指数+ +){ 布尔多钩长线=mRulerHelper.isLongLine(指数); int lineCount=mLineWidth *指数; mRect。左=指数* mLineSpace + lineCount + mMarginLeft; mRect。顶级=getStartY(延绳钓); mRect。正确的=mRect。左+ mLineWidth; mRect。底=getEndY (); 如果(延绳钓){ 如果(! mRulerHelper.isFull ()) { mRulerHelper.addPoint (mRect.left); } 字符串文字=mRulerHelper.getTextByIndex (mTextIndex); mTextIndex + +; 画布。drawText(文本、mRect.centerX (), getMeasuredHeight ()——dpFor14 mTextPaint); } 画布。绘制矩形(mRect mLinePaint); mRect.setEmpty (); } }
这里解释一下为什么刻度采用矩形而不是设置线的宽度,其实最简单的就是设置油漆的宽度然后canvas.drawLine()。刚绘制的时候就是采用的canvas.drawLine(),绘制完之后发现每个刻度的宽度都被削减了一半,canvas.drawLine()是在设置的(x, y)坐标开始平分线的宽度的(这个你要去体验一下就会明白)。所以给定坐标之后每个刻度看起来就像是被挤了一样,所以才采用矩形简单方便一点。进入正题,绘制有几个问题:
-
<李>怎么确定要绘制几个矩形?李>
这个比较灵活,要看具体的需求了。也就是一大格里面包含几个刻度,一般是包含10个刻度,刻度包括长短刻度。然后一大格刻度表示多少数值,也就是偏移值是多少。之后刻度的范围也要明确并且能被抵消整除,比如范围是(低、高度),那么(height-low)/(抵消/10)就是你需要绘制多少个刻度。
公共空间setScope (int, int数,int抵消){ 如果(抵消!=0){ 这一点。抵消=抵消; } lineNumbers=(计数-开始)/(这。抵消/10); }
-
<李>怎么确定那个是长刻度?李>
这个问题要确定一大格之间有几个小刻度了,一般为10个的话,那么当前的索引/10能整除就是到了该绘制长刻度的时候了,mRulerHelper.getCounts()就是我们计算出的总共有几个刻度。
for (int指数=0;指数& lt;=mRulerHelper.getCounts ();指数+ +){ 布尔多钩长线=mRulerHelper.isLongLine(指数); … 如果(延绳钓){ 画布。drawText(文本、mRect.centerX (), getMeasuredHeight ()——dpFor14 mTextPaint); } 画布。绘制矩形(mRect mLinePaint); }
之后呢就是我们计算矩形的左边跟绘制文本的坐标了…不细讲,具体可看这里啊。
有个问题就是你得明白矩形的左右上角底分别表示那个区间:
[图片上传失败…(图片- 5 - d1f26 - 1554206618213)]