一 基础:
自定义View实现跟随手指滚动的刻度尺,实现了类似SeekBar的滑动选中效果。项目地址,欢迎star!
UI图:
功能:
- 通过设置最小值跟最大值的范围,以及offset值。View将根据这些数据去计算出需要几个小刻度和几个长刻度,和每个长刻度上面显示的数值。
- 指针可以随意的定制。
- 当滑动停止后,刻度尺会根据四舍五入将距离指针最近的长刻度滑动到指针的位置。
- 支持范围越界回弹。
- 支持设置默认值。
二 实现:
先扯一下,再看别人写的控件的时候总有一种一脸懵逼的感觉,好多凌乱的变量和一大堆的计算逻辑都不知道干嘛用的。比如:PullToRefreshLayout。除非自己按着整体的设计流程写一遍,一步步的写,等出了bug你就明白那些操作的价值。结合之前读第三方控件的经验,写这个刻度尺控件的时候就一步步的去完成,从简单的绘制,到点击事件,再到滑动fling,最后滑动结束更正滑动位置。每一步遇到的问题都记录下来,之后再补全解决方法,这就是成长。
1.绘制刻度
这里省略了onMeasure,这里的需求只是计算一下高度就好了。接着看onDraw方法:
private void drawRuler(Canvas canvas) {
mTextIndex = 0;
for (int index = 0; index <= mRulerHelper.getCounts(); index++) {
boolean longLine = mRulerHelper.isLongLine(index);
int lineCount = mLineWidth * index;
mRect.left = index * mLineSpace + lineCount + mMarginLeft;
mRect.top = getStartY(longLine);
mRect.right = mRect.left + mLineWidth;
mRect.bottom = getEndY();
if (longLine) {
if (!mRulerHelper.isFull()) {
mRulerHelper.addPoint(mRect.left);
}
String text = mRulerHelper.getTextByIndex(mTextIndex);
mTextIndex++;
canvas.drawText(text, mRect.centerX(), getMeasuredHeight() - dpFor14, mTextPaint);
}
canvas.drawRect(mRect, mLinePaint);
mRect.setEmpty();
}
}
这里解释一下为什么刻度采用Rect而不是设置line的宽度,其实最简单的就是设置Paint的宽度然后canvas.drawLine()。刚绘制的时候就是