BooheeRuler
这是仿写薄荷健康里面体重选择尺的控件,因为最新的 0.1.x 版本经历重大更新(重构,把尺子分成多种形式),所以重新写一个 README 来介绍(旧的 README 在这里):
最初是为了参加 HenCoder 的活动,最后也获奖了,谢谢 HenCoder 凯哥!
介绍
由于不少伙伴们发邮件或者 issue 让我做纵向的尺子,其实我也很想做,但是最近项目有点忙,最后就只能在不太忙的阶段偷偷把它做出来了,欢迎大家使用,多多指教小弟哈。 这次更新主要是把 InnerRuler 里面的一些公共的逻辑提取出来,做成抽象类,然后再由两个 HorizontalRuler 和 VerticalRuler 继承它,再实现一些公共逻辑的处理,最后实现四个类型的子类:LeftHeadRuler、TopHeadRuler、RightHeadRuler、BottomHeadRuler。**这样能大大减少重复的代码,缺点就是逻辑分开了,想通过代码看实现一个尺子的逻辑就要跳来跳去有点不方便。具体的重构思路在这
要是想参考下一个完整的尺子的实现逻辑,可以看上一个版本 0.0.7 的代码,直接在 Gradle 里面:
compile 'com.yanzhikai:BooheeRuler:0.0.7'
就可以了。
使用
Gradle
compile 'com.yanzhikai:BooheeRuler:0.1.6'
使用方法
Demo 里面有 4 个尺子,这里就写一个,因为都是差不多的。BooheeRuler 分成两个部分,一个是上面的显示多少 kg 的数字 Layout,还有一个就是下面的尺子。首先在 xml 文件里调用(下面属性的作用可以看后面的表格):
<!--数字和单位-->
<yanzhikai.ruler.KgNumberLayout
android:id="@+id/knl_bottom_head"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:kgTextSize="20sp"
app:scaleTextSize="50sp" />
<!--尺子-->
<yanzhikai.ruler.BooheeRuler
android:id="@+id/br_top_head"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
app:bigScaleLength="40dp"
app:bigScaleWidth="2.5dp"
app:count="10"
app:currentScale="666"
app:cursorDrawable="@drawable/cursor_shape"
app:cursorHeight="45dp"
app:cursorWidth="4dp"
app:maxScale="2000"
app:minScale="464"
app:numberTextSize="22sp"
app:paddingStartAndEnd="10dp"
app:rulerStyle="TOP_HEAD"
app:scaleInterval="11.5dp"
app:smallScaleLength="20dp"
app:smallScaleWidth="1.5dp"
app:textMarginHead="80dp" />
然后在 java 代码里面使用:
public class MainActivity extends AppCompatActivity {
private BooheeRuler br_top_head;
private KgNumberLayout knl_top_head;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
br_top_head = (BooheeRuler) findViewById(R.id.br_top_head);
knl_top_head = (KgNumberLayout) findViewById(R.id.knl_top_head);
knl_top_head.bindRuler(br_top_head);
}
}
BooheeRuler 的使用环境是 API >= 16
属性
BooheeRuler 的属性
属性名称 | 意义 | 类型 | 默认值 |
---|---|---|---|
minScale | 尺子的最小刻度值 | integer | 464,在尺子上显示就是 464 * factor |
maxScale | 尺子的最大刻度值 | integer | 2000,在尺子上显示就是 200 * factor |
smallScaleLength | 尺子小刻度(0.1)的刻度线长度 | dimension | 30px |
smallScaleWidth | 尺子小刻度(0.1)的刻度线宽度/粗细 | dimension | 3px |
bigScaleLength | 尺子大刻度(1.0)的刻度线长度 | dimension | 60px |
bigScaleWidth | 尺子大刻度(1.0)的刻度线宽度/粗细 | dimension | 5px |
cursorHeight | 尺子中间的选定光标的刻度图高度 | dimension | 70px |
cursorWidth | 尺子中间的选定光标的刻度图宽度 | dimension | 8px |
尺子数字文字距离边界距离 | dimension | 120px | |
numberTextSize | 尺子数字文字大小 | dimension | 28px |
scaleInterval | 尺子每条刻度线之间的距离 | dimension | 18px |
numberTextColor | 尺子数字文字颜色 | color | #2B2E2B |
scaleColor | 尺子刻度线的颜色 | color | #e2e5e2 |
currentScale | 尺子初始选定刻度 | float | (maxScale + minScale)/2 |
cursorDrawable | 尺子中间选定光标的 Drawable(会把 drawable 伸缩到设定的宽高上) | dimension | @drawable/cursor_shape |
count | 一个大刻度格子里面的小刻度格子数 | integer | 10 |
paddingStartAndEnd | 控制尺子两端的 padding | dimension | 0 |
canEdgeEffect (new) | 是否启用边缘效果 | boolean | true |
edgeColor (new) | 边缘效果的颜色(API 大于等于 21 设置才有效) | color | #4bbb74 |
rulerBackGround | 尺子的背景 | reference 或者 color | #f6f9f6 |
factor(new) | 乘积因子,尺子刻度值实际显示为:scale * factor | float | 0.1 |
rulerStyle | 尺子的形态(下面有具体介绍) | enum | TOP_HEAD |
接下来是选择尺子形态的属性 rulerStyle:
rulerStyle 选项 | 意义 |
---|---|
TOP_HEAD | 头部向上的尺子 |
BOTTOM_HEAD | 头部向下的尺子 |
LEFT_HEAD | 头部向左的尺子 |
RIGHT_HEAD | 头部向右的尺子 |
如效果图中,对应位置的尺子的 rulerStyle 为:上——BOTTOM_HEAD,下——TOP_HEAD,左——RIGHT_HEAD,右——LEFT_HEAD。
使用 setXX()方法改变一些尺子属性的时候,请调用refreshRuler()
方法让尺子重新初始化,不然数值可能会错乱,出现一堆 bug。除了setCurrentScale()
,这个不用刷新,会直接执行跳转。
factor 说明
相当于设置每个刻度的最小单位。如 factor 等于 5 时:
注意,回调中的 scale 值还是原来的 currentScale,所以在 KgNumberLayout 里面做的处理改成:
@Override
public void onScaleChanging(float scale) {
if (mRuler != null) {
tv_scale.setText(RulerStringUtil.resultValueOf(scale, mRuler.getFactor()));
}
}
边缘效果说明
0.1.2 版本新增的效果,在 API 大于等于 21(Android5.0)的时候是这样的效果:
在 API 小于 21(Android5.0)的时候是这样的效果:
KgNumberLayout 属性
属性名称 | 意义 | 类型 | 默认值 |
---|---|---|---|
scaleTextSize | 数字字体大小 | dimension | 80 |
kgTextSize | 单位字体大小 | dimension | 40 |
scaleTextColor | 数字字体颜色 | color | #4bbb74 |
kgTextColor | 单位字体颜色 | color | #4bbb74 |
kgUnitText | 单位文字内容 | string | kg |
接口
除了使用 KgNumberLayout 作为显示 BooheeRuler 的当前刻度之外,还可以通过实现 RulerCallback 回调接口来获取当前选定刻度:
public interface RulerCallback {
//选取刻度变化的时候回调
//注意,scale 值不一定是实际值,大概值是实际值/factor
void onScaleChanging(float scale);
}
实现了这个接口之后,再调用BooheeRuler.setCallback(RulerCallback rulerCallback)
方法传入即可。
PS:由于 0.1.4 更新了 factor 属性,所以推荐使用
RulerStringUtil.resultValueOf(scale, mRuler.getFactor())
方法来将 scale 属性转化为 String,具体可以参考 KgNumberLayout 的源码。
更新
- 2017/10/23 version 0.0.5:
- 修改了画刻度的方法,改为只画当前屏幕显示的刻度
- 增加了 count 属性,用于设置一个大刻度格子里面的小刻度格子数,默认是 10
- 2017/10/30 version 0.0.6:
- 加入 VelocityTracker 的回收处理(之前只是 clear 并没有 recycle),提高性能。
- 加入属性
paddingStartAndEnd
,用于控制尺子两端的 padding。 - 让刻度的绘制前后多半大格,这样可以提前显示出下面的数字,让过渡不会变得那么突兀。
- 取消了一些不必要的 log 输出。
非常感谢JulianAndroid为我指出来 VelocityTracker 这个错误。
2017/10/30 version 0.0.7:
- 之前 VelocityTracker 重复使用了 addMovement,现在取消掉了。
2017/11/15 version 0.1.0:
- 重构代码,将尺子分为 4 个形态。
- 对细节有一些小改动:如背景设置换成以 InnerRuler 为主体,优化 Padding 等。
- 2017/11/16 version 0.1.1:
- 修复 KgNumberLayout 修改单位会出错的 bug
- 2017/11/28 version 0.1.2:
- 修复触发 ACTION_CANCEL 事件会令刻度停在非整点地方的 bug
- 增加边缘效果
- 2017/12/13 version 0.1.3:
- 性能优化:BooheeRuler 的 onLayout 之前没有利用 change 属性,导致每次刷新都会重新 Layout,现在不会。
- 性能优化:修改了画刻度的逻辑,现在在刻度范围很大的情况下还可以顺畅滑动。
- 修复了 goToScale()重复回调导致显示刻度不准确的问题。
非常感谢littlezan提出的性能优化建议。
- 2017/12/25 version 0.1.4:
- 功能增加:增加属性 factor,乘积因子,可以调节刻度值具体最小单位,默认值是 0.1。如 currentScale 是 464 时,显示出的值为 464 * 0.1 = 46.4。增加了
RulerStringUtil
类来处理回调方法的 scale 值。
- 功能增加:增加属性 factor,乘积因子,可以调节刻度值具体最小单位,默认值是 0.1。如 currentScale 是 464 时,显示出的值为 464 * 0.1 = 46.4。增加了
- 2017/12/28 version 0.1.5:
- 修复使用 setXX()方法改变一些尺子属性的时候,会导致各种错乱的情况。措施:请使用完 setXX()方法改变属性之后,调用
refreshRuler()
方法让尺子重新初始化。(除了setCurrentScale()
,这个不用刷新,会直接执行跳转,之前忘记说了,以为就算刷新了也没什么问题,不好意思。。。)
- 修复使用 setXX()方法改变一些尺子属性的时候,会导致各种错乱的情况。措施:请使用完 setXX()方法改变属性之后,调用
- 2019/1/1 version 0.1.6:
- 没想到隔了一年才更新,可怕。修复了因为刻度转 px 值 float 转 int 丢失的精度可能会导致无限绘制的问题。
非常感谢levianye发现 Bug 并提出修复建议和 PR。 非常感谢madongqiang2201发现 Bug 并提出修复建议。
开源协议
BooheeRuler 遵循 MIT 协议。
关于作者
id:炎之铠
炎之铠的邮箱:yanzhikai_yjk@qq.com