android 带刻度的滑动条_Android滚动刻度尺实现
缘起
最近在帮人做一个计步器,其中涉及到身高、体重等信息的采集;我参考了众多app的实现,觉得"乐动力"中滑动刻度的方式比较优雅。于是乎,反编译了该app,结果发现它是采用图片的方式实现的,即ScrollView内嵌了一张带刻度的图片。
个人觉得该方式太不灵活,且对美工的依赖较大,于是便想自定义一个刻度尺控件。
需求分析
绘制刻度,区分整值刻度和普通刻度
红色指针始终在刻度尺的中间,表示当前的刻度
刻度的最大值和最小值可动态设置
刻度尺的高度或宽度可设置,设置后中间刻度不变
可滑动,滑动后当前刻度随之改变
涉及的知识点
View的机制
canvas绘图
Scroller工具类的使用
自定义View的属性
点击、滑动事件的处理
最终效果
由于简书上无法嵌入gif,为不影响效果,请移步github查看,如果觉得不错,帮忙给个star _
https://github.com/LichFaker/ScaleView
实现过程
新建一个class:HorizontalScaleScrollView, 继承自View
在构造方法中获取自定义属性:
protected void init(AttributeSet attrs) {
// 获取自定义属性
TypedArray ta = getContext().obtainStyledAttributes(attrs, ATTR);
mMin = ta.getInteger(LF_SCALE_MIN, 0);
mMax = ta.getInteger(LF_SCALE_MAX, 200);
mScaleMargin = ta.getDimensionPixelOffset(LF_SCALE_MARGIN, 15);
mScaleHeight = ta.getDimensionPixelOffset(LF_SCALE_HEIGHT, 20);
ta.recycle();
mScroller = new Scroller(getContext());
}
重写onMeasure,计算中间刻度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height=MeasureSpec.makeMeasureSpec(mRectHeight, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, height);
mScaleScrollViewRange = getMeasuredWidth();
mTempScale = mScaleScrollViewRange / mScaleMargin / 2 + mMin;
mMidCountScale = mScaleScrollViewRange / mScaleMargin / 2 + mMin;
}
重写onDraw,绘制刻度和指针
protected void onDrawScale(Canvas canvas, Paint paint) {
paint.setTextSize(mRectHeight / 4);
for (int i = 0, k = mMin; i <= mMax - mMin; i++) {
if (i % 10 == 0) {
//整值
canvas.drawLine(i * mScaleMargin, mRectHeight, i * mScaleMargin, mRectHeight - mScaleMaxHeight, paint);
//整值文字
canvas.drawText(String.valueOf(k), i * mScaleMargin, mRectHeight - mScaleMaxHeight - 20, paint);
k += 10;
} else {
canvas.drawLine(i * mScaleMargin, mRectHeight, i * mScaleMargin, mRectHeight - mScaleHeight, paint);
}
}
}
protected void onDrawPointer(Canvas canvas, Paint paint) {
paint.setColor(Color.RED);
//每一屏幕刻度的个数/2
int countScale = mScaleScrollViewRange / mScaleMargin / 2;
//根据滑动的距离,计算指针的位置【指针始终位于屏幕中间】
int finalX = mScroller.getFinalX();
//滑动的刻度
int tmpCountScale = (int) Math.rint((double) finalX / (double) mScaleMargin);//四舍五入取整
//总刻度
mCountScale = tmpCountScale + countScale + mMin;
if (mScrollListener != null) { //回调方法
mScrollListener.onScaleScroll(mCountScale);
}
canvas.drawLine(countScale * mScaleMargin + finalX, mRectHeight,
countScale * mScaleMargin + finalX, mRectHeight - mScaleMaxHeight - mScaleHeight, paint);
}
处理滑动事件
在手指按下时,记录当前的x坐标(针对水平刻度尺)。
在手指滑动过程中,判断当前指针所指的刻度是否已经超出了边界,如果超出,则禁止滑动,同时刷新当前界面。
在手指抬起时,校正当前的刻度。
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mScroller != null && !mScroller.isFinished()) {
mScroller.abortAnimation();
}
mScrollLastX = x;
return true;
case MotionEvent.ACTION_MOVE:
int dataX = mScrollLastX - x;
if (mCountScale - mTempScale < 0) { //向右边滑动
if (mCountScale <= mMin && dataX <= 0) //禁止继续向右滑动
return super.onTouchEvent(event);
} else if (mCountScale - mTempScale > 0) { //向左边滑动
if (mCountScale >= mMax && dataX >= 0) //禁止继续向左滑动
return super.onTouchEvent(event);
}
smoothScrollBy(dataX, 0);
mScrollLastX = x;
postInvalidate();
mTempScale = mCountScale;
return true;
case MotionEvent.ACTION_UP:
if (mCountScale < mMin) mCountScale = mMin;
if (mCountScale > mMax) mCountScale = mMax;
int finalX = (mCountScale - mMidCountScale) * mScaleMargin;
mScroller.setFinalX(finalX); //纠正指针位置
postInvalidate();
return true;
}
return super.onTouchEvent(event);
}
最后的说明
以上只是针对水平滑动刻度的实现,垂直滑动原理一致,在源码中已经实现,其中也有许多不够完善的地方,如:
第一次快速滑动时,可以超出边界,之后则不会;
开放的自定义属性不够(根据具体情况);
可以考虑将水平和垂直的实现,在一个类中完成,因为在实现过程中发现其实有很多代码都是类似的,只是个别参数属性的不同,在坐标系中,垂直可以看成是水平旋转了90°,之后有时间可以朝这个方向尝试下。
android 带刻度的滑动条_Android滚动刻度尺实现相关推荐
- android 带刻度的滑动条_android 滚轮刻度尺的实现
遇到一个需求需要实现如下图的效果: 卷尺,通过左右滑动来选择不同的刻度值.这方面的东西以前没弄过,以目前你的能力,想了几种思路都死在了半路上.比如上面的刻度线如何弄,滑动的时候又该如何弄:下面的数字又 ...
- android 带刻度的滑动条_Android实现滑动刻度尺效果
最近群里的开发人员咨询怎样实现刻度尺的滑动效果去选择身高体重等信息.给个横着的效果,自己试着去改编或者修改一下,看看通过自己的能力能不能做出竖着的效果来,过两天我再把竖着的那个滑动选择效果分享出来.废 ...
- android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺
自定义控件是件很有乐趣的事,慢慢的会爱上它,哈哈哈.废话不多说先上设计图 接下来我们我们要先分析一下页面中需要到哪些东西 1.一条无限长的底线: 2.一根在屏幕中间的红色标记线,代表当前位置: 3.一 ...
- Android 带文字的进度条,文字颜色随进度条的增加而渐变的效果
Android自带的ProgressBar是不带文字的,加文字的话可以参考这篇博客:http://blog.csdn.net/lixiaodaoaaa/article/details/9852327 ...
- Android ScrollView去掉右侧滑动条
<ScrollView ......android:scrollbars="none"><!--添加代码-->
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...
- wdatepicker设置初始时间_滑动条的滑块的初始位置应该放在哪儿?
滑动条(slider question)是网络调查中独有的一种题型,它由一个有刻度的轴和一个可在轴上来回拖动的滑块组成.受访者在PC或手机屏幕上,通过鼠标或者手指将滑块移动至轴上相应的位置,来完成答题 ...
- 【Unity】讲解如何在Unity的Inspector面板中用滑动条来控制变量的大小
首先,我们现在的需求是这样的,我定义了一个脚本,里面有一个int类型的变量,但是我想控制变量的大小在0到100之间,通过用滑动条的方式来控制. 其实这里的player HP 是我使用了unity自带的 ...
- Android——自定义带刻度的SeekBar单向拖动条
时间过得真快,才发现好久没来逛逛了.没写博客的这段时间一直在做项目,连续完成了两个大型app,这个过程很享受,这是独立开发的,所以中途有很多很多的问题需要自己一个一个的去解决,现在接近尾声了,发现自己 ...
- android gridview滑动监听,Android GridView 滑动条设置一直显示状态(推荐)
Android GridView 滑动条设置一直显示状态(推荐) 模拟GridView控件: android:id="@+id/picture_grid" android:layo ...
最新文章
- CS131专题-2:高斯核、噪声、滤波
- Python抓取新浪新闻数据(三)
- JavaScript初学者编程题(10)
- [转]Git忽略提交规则 - .gitignore配置运维总结
- git bash命令_?你可能不太会用的10个Git命令
- custom field further usage - add into UI and report
- .NET内存性能分析指南
- Java和Lagom的CQRS
- Html如何触发闹铃,事件闹钟设置.html
- cad中简单流程图制作_Excel vba 简单制作流程图方法介绍
- excel oledb mysql_C#实战023:OleDb操作-Excel数据写入
- visio素材:安防监控visio素材图库
- 平面内 两直线/两向量的夹角方向 逆时针 还是顺时针
- 树莓派怎么切换输入法_树莓派如何安装中文输入法
- 学习关于Bootstrap的感悟和体会
- 交换安全----局域网安全简介
- itms-services php,APP发布系统 ipa文件上传和下载 itms-service协议
- Android商城项目
- python实现图片批量重命名
- 拆解一个居家隔离监测的无线门磁