缘起

最近在帮人做一个计步器,其中涉及到身高、体重等信息的采集;我参考了众多app的实现,觉得"乐动力"中滑动刻度的方式比较优雅。于是乎,反编译了该app,结果发现它是采用图片的方式实现的,即ScrollView内嵌了一张带刻度的图片。

个人觉得该方式太不灵活,且对美工的依赖较大,于是便想自定义一个刻度尺控件。

需求分析

绘制刻度,区分整值刻度和普通刻度

红色指针始终在刻度尺的中间,表示当前的刻度

刻度的最大值和最小值可动态设置

刻度尺的高度或宽度可设置,设置后中间刻度不变

可滑动,滑动后当前刻度随之改变

涉及的知识点

View的机制

canvas绘图

Scroller工具类的使用

自定义View的属性

点击、滑动事件的处理

最终效果

由于简书上无法嵌入gif,为不影响效果,请移步github查看,如果觉得不错,帮忙给个star ^_^https://github.com/LichFaker/ScaleView

实现过程

1、新建一个class:HorizontalScaleScrollView, 继承自View

2、在构造方法中获取自定义属性:

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());

}

3、重写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;

}

4、重写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实现滚动刻度尺效果

本文地址: http://www.cppcns.com/ruanjian/android/192336.html

android 带刻度的滑动条_Android实现滚动刻度尺效果相关推荐

  1. android 带刻度的滑动条_android 滚轮刻度尺的实现

    遇到一个需求需要实现如下图的效果: 卷尺,通过左右滑动来选择不同的刻度值.这方面的东西以前没弄过,以目前你的能力,想了几种思路都死在了半路上.比如上面的刻度线如何弄,滑动的时候又该如何弄:下面的数字又 ...

  2. android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺

    自定义控件是件很有乐趣的事,慢慢的会爱上它,哈哈哈.废话不多说先上设计图 接下来我们我们要先分析一下页面中需要到哪些东西 1.一条无限长的底线: 2.一根在屏幕中间的红色标记线,代表当前位置: 3.一 ...

  3. android 带刻度的滑动条_Android实现滑动刻度尺效果

    最近群里的开发人员咨询怎样实现刻度尺的滑动效果去选择身高体重等信息.给个横着的效果,自己试着去改编或者修改一下,看看通过自己的能力能不能做出竖着的效果来,过两天我再把竖着的那个滑动选择效果分享出来.废 ...

  4. Android 带文字的进度条,文字颜色随进度条的增加而渐变的效果

    Android自带的ProgressBar是不带文字的,加文字的话可以参考这篇博客:http://blog.csdn.net/lixiaodaoaaa/article/details/9852327 ...

  5. Android ScrollView去掉右侧滑动条

    <ScrollView ......android:scrollbars="none"><!--添加代码-->

  6. android刷新时的圆形动画_Android 实现倒计时动画效果

    本文没有写作背景,在闲暇之余,想巩固下用到的知识,才有了这篇文章的产出.觉得内容太简单的神们,可以绕道了,不过如果是个神,还是个喷子,可以留下改进建议再走也不迟. 想要实现的效果图如下: 点击&quo ...

  7. 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

    http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...

  8. Python Qt GUI设计:QSlider滑动条类(基础篇—16)

    QSlider控件提供了一个垂直或水平的滑动条,滑动条是一个用于控制有界值的典型控件,它允许用户沿水平或垂直方向在某一范围内移动滑块,并将滑块所在的位置转换成一个合法范围内的整数值. 有时候这种方式比 ...

  9. wdatepicker设置初始时间_滑动条的滑块的初始位置应该放在哪儿?

    滑动条(slider question)是网络调查中独有的一种题型,它由一个有刻度的轴和一个可在轴上来回拖动的滑块组成.受访者在PC或手机屏幕上,通过鼠标或者手指将滑块移动至轴上相应的位置,来完成答题 ...

  10. 【Unity】讲解如何在Unity的Inspector面板中用滑动条来控制变量的大小

    首先,我们现在的需求是这样的,我定义了一个脚本,里面有一个int类型的变量,但是我想控制变量的大小在0到100之间,通过用滑动条的方式来控制. 其实这里的player HP 是我使用了unity自带的 ...

最新文章

  1. 你还在从零搭建项目 ?
  2. ElasticSearch知识汇总
  3. 企业过快移向MBaaS很危险
  4. [Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算
  5. 有多个重载参数pow_随时随地想充就充,同时最多能给三部手机充电的南卡无线充电宝POW-1体验...
  6. 专家建议用南方的养老金拿去救济东北,网友炸锅了
  7. python 串口助手 简书_python用pyserial读取串口问题解决
  8. 别再用Else语句写代码了!
  9. dedecms织梦第三方登录插件-QQ登录、微博登录、微信登录
  10. linux-inject:注入代码到运行的Linux进程中
  11. 3.netwox网络工具集入门教程
  12. 【日志分析】Window日志分析
  13. 682. Baseball Game 棒球游戏 按字母处理
  14. 压缩包修改所属目录Linux,linux文件/目录/压缩解压 操作指令
  15. 知乎7w阅读!五面阿里拿下飞猪事业部offer,月薪30K
  16. SSO - 我们为何需要单点登录系统
  17. 第5篇-分析北京租房的房源信息
  18. elo匹配算法c语言,匹配算法全面解析:采用国际通用“ELO等级分系统”
  19. Struts2中的OGNL表达式的详解
  20. 嵌入式新闻早班车-第9期

热门文章

  1. 【Vue】13.解决安卓手机上调出软键盘,屏幕背景被压缩的问题
  2. java基础——多态
  3. 产品经理vs项目经理?四类PM区别都在这里啦
  4. Android 获取/设置:窝蜂移动数据网络状态
  5. 编码人大脑的5大小吃
  6. python中类名(..)(..)的情况及_call_函数解析
  7. 酷睿i7 1260p怎么样 i71260p参数
  8. 简单分析RTMP规范
  9. 阿里云数据库(RDS)是什么,与传统数据库有什么区别?
  10. Google提供Fastboot和ADB单独下载服务(转载)