自定义 View 循环滚动刻度控件

LoopScaleView

先看效果图:

enter description here

LoopScaleView 是一个自定义的刻度尺风格的选值控件,从上面的动图大家可以看到 LoopScaleView 的运行效果.可以设置屏幕内显示的刻度数,也可以设置每一个刻度代表的值得大小。

LoopScaleView.class

Nested class

OnValueChangeListener刻度取值监听接口

Public methods

方法名返回值类型说明
getItemsCount()int获取总的刻度数
setCursorColor(int color)void设置游标颜色(游标不采用图片时)
setCursorWidth(int width)void设置游标宽度(同上)
setCursorMap(Bitmap map)void设置图片作为游标
setScaleWidth(int scaleWidth)void设置刻度宽度
setShowItemSize(int showItemSize)void设置屏幕内可见的大刻度数
setScaleHeight(float scaleHeight)void设置刻度的高度
setLineColor(int lineColor)void设置底部直线的颜色
setScaleTextColor(int scaleTextColor)void设置刻度标值的颜色
setScaleTextSize(int scaleTextSize)void设置刻度标值的文字大小
setMaxValue(int maxValue)void设置最大值
setOneItemValue(int oneItemValue)void设置一个刻度表示的值的大小
setCurrentValue(int currValue)void设置当前的值

分解剖析

  • onMeasure 方法中初始化一个刻度的像素宽度,整个视图的宽度
      @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);viewHeight = MeasureSpec.getSize(heightMeasureSpec);//一个小刻度的宽度(十进制,每5个小刻度为一个大刻度)scaleDistance = getMeasuredWidth() / (showItemSize * 5);//尺子长度总的个数*一个的宽度viewWidth = maxValue / oneItemValue * scaleDistance;maxX = getItemsCount() * scaleDistance;minX = -maxX;}复制代码
  • onDraw() 方法重写绘制 ScaleView 的视图
      @Overrideprotected void onDraw(Canvas canvas) {canvas.clipRect(getPaddingStart(), getPaddingTop(), getWidth() - getPaddingRight(), viewHeight - getPaddingBottom());// 绘制底部线条drawLine(canvas);// 绘制游标drawCursor(canvas);paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setStrokeWidth(scaleWidth);// 绘制反向的一个刻度尺for (int i = 0; i < maxValue / oneItemValue; i++) {//drawScale 为绘制刻度线的方法drawScale(canvas, i, -1);}//绘制正向的一个刻度尺for (int i = 0; i < maxValue / oneItemValue; i++) {//drawScale 为绘制刻度线的方法drawScale(canvas, i, 1);}}复制代码
    可以看出上面的绘制过程,实际上是绘制出了两个刻度尺。经过上面的步骤,静止状态下的 ScaleView 已经绘制完成,接下来就是要让他动起来了
  • 手势识别来处理滑动
    在 onTouchEvent() 方法中将触摸事件交给手势识别 GestureDetector.SimpleOnGestureListener 来处理:

      /*** 滑动手势处理*/private GestureDetector.SimpleOnGestureListener gestureListener = new GestureDetector.SimpleOnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {return true;}//滚动事件public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {scrollView(distanceX);return true;}//快速滑动时间public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {if (!mScroller.computeScrollOffset()) {mScroller.fling((int) currLocation, 0, (int) (-velocityX / 1.5), 0, minX, maxX, 0, 0);setNextMessage(0);}return true;}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return super.onSingleTapUp(e);}};复制代码

    上述代码主要注意两个地方:onScroll() 和 onFling()。当正常左右滑动时,触发 onScroll 方法调用 srcollView(float distance) 对整个视图进行重绘。当快速惯性滑动时通过 Scroller 让惯性滑动变得流畅,惯性滑动的状态更新是通过 Handler 进行不断的查询 Scroller 的执行状态得到的,当 Scroller 执行完惯性滑动的动画到达目的地时,停止 Handler 的查询任务,当 onFling 多次触发时只会执行第一次的状态。

  • 循环滚动的实现
    开始说到的绘制了正向反向两个方向的刻度尺即是为了实现循环滚动而设定的,在 drawScale() 方法中有如下代码:
          if (currLocation + showItemSize / 2 * 5 * scaleDistance >= viewWidth) {currLocation = -showItemSize / 2 * 5 * scaleDistance;float speed = mScroller.getCurrVelocity();mScroller.fling((int) currLocation, 0, (int) speed, 0, minX, maxX, 0, 0);setNextMessage(0);} else if (currLocation - showItemSize / 2 * 5 * scaleDistance <= -viewWidth) {currLocation = showItemSize / 2 * 5 * scaleDistance;float speed = mScroller.getCurrVelocity();mScroller.fling((int) currLocation, 0, (int) speed, 0, minX, maxX, 0, 0);setNextMessage(0);}复制代码
    当 currLocation 加上可视视图一半的距离大于刻度尺的宽度 viewWidth 或者 currLocation 减去可视视图一半的距离小于 -viewWidth 时(即正向或者反向滑到最大/最小值时)通过为 currLocation 重新赋值将刻度值重置,来达到循环滚动的目的.如果到达临界点时是在 Scroller 执行快速滑动的过程则重置之后需要再为 Scroller 重新设置初速度来达到流畅的滑动.
    基本思路就是上面所说的这样了,详细操作大家自己查看 LoopScaleView 的源码。

    接入使用

    project's build.gradle (工程的 build.gradle)
    allprojects {repositories {jcenter()maven{url  "http://dl.bintray.com/huxinyu/maven"}}
    }复制代码
    module's build.gradle (模块的build.gradle)
    dependencies {compile 'com.pandaq:loopscale:1.0.1'
    }复制代码
  • xml 文件中进行属性配置,这些属性也可以通过 Java 代码进行修改
      <com.pandaq.loopscaleview.LoopScaleViewandroid:id="@+id/lsv_4"android:layout_width="match_parent"android:layout_height="50dp"android:layout_margin="8dp"android:background="@drawable/loopscaleview_bg"android:padding="8dp"app:cursorColor="@color/colorAccent"app:maxShowItem="4"app:maxValue="1000"app:oneItemValue="5"app:scaleTextColor="@color/colorPrimary"/>复制代码

    最后

    觉得本文对你有帮助
    简书PandaQ404
    掘金PandaQ
    GithubPandaQAQ
    持续分享中,欢迎关注和 star。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go 类型断言_(57)接口的类型断言

GO提供了一个方法&#xff0c;用来判断接口的底层值是什么类型类型断言 提供了访问接口值底层具体值的方式。t : i.(T)该语句断言接口值 i 保存了具体类型 T&#xff0c;并将其底层类型为 T 的值赋予变量 t。若 i 并未保存 T 类型的值&#xff0c;该语句就会触发一个panic。为了…

使用web3j构建以太坊钱包

创建一个以太坊钱包有多种方式&#xff0c;一般情况下可以通过geth、EtherumWallet等客户端。对于前端&#xff0c;可以使用插件MetaMask进行创建。这几种方式技术实现虽然不同&#xff0c;但底层原理是一致的。本文主要介绍如何通过web3j架构创建一个以太坊的冷钱包&#xff0…

Html、CSS、JavaScript 实时效果在线编辑器 - 学习的好工具,算不算?!

关于 二维码 与 NFC 之间的出身贫贱说太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es)本文遵循“署名-非商业用途-保持一致”创作公用协议转载请保留此句&#xff1a;太阳火神的漂亮人生 - 本博客专注于 敏捷开发及移动和物联设备研究&#xff1a;iOS、Android、Html5、…

android自定义更新,Android 完美解决自定义preference与ActivityGroup UI更新的问题

之前发过一篇有关于自定义preference 在ActivityGroup 的包容下出现UI不能更新的问题&#xff0c;当时还以为是Android 的一个BUG 现在想想真可笑 。其实是自己对机制的理解不够深刻&#xff0c;看来以后要多看看源码才行。本篇讲述内容大致为如何自定义preference 开始到与Act…

vxlan 资料及其在 neutron中的应用

2019独角兽企业重金招聘Python工程师标准>>> VXLAN 是一个新兴的SDN 标准&#xff0c;它定义了一种新的 overlay 网络&#xff0c;它主要的创造者是 VMware, Cisco 和 Arista。它被设计来消除虚拟化网络世界中的 VLAN 数目的限制。VXLAN 本身是一个多播标准&#xf…

横流式冷却塔计算风量_研讨丨卓展标准高效制冷机房技术之影响冷却塔效率的几个因素...

集中制冷用空调系统中&#xff0c;单台冷却塔的冷却水量基本上都小于1,000m/h&#xff0c;且装有淋水填料的横流机械通风开式居多。本文将已横流开式冷却塔为对象&#xff0c;探讨影响其效率的几个因素。横流开式冷却塔示意图如下所示&#xff1a;横流开式冷却塔示意图 Fig 01说…

我是培训出来的我怕谁

引子: 江小峰是我带过的徒弟中跟我最久&#xff0c;也是最聪明的一个。 他一个高中生&#xff0c;没上过大学&#xff0c;高中毕业后在老家卖了三年电脑&#xff0c;天天给人装操作系统&#xff0c;有天他在网上看到某培训机构招生简介&#xff0c;一时冲动揣上三年血汗钱&…

android平台gallery2应用分析,Android5.1图库Gallery2代码分析数据加载流程

图片数据加载流程。Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->PhotoPage相册集 照片集 某张图片1,AlbumSetPage.javaprivate void initializeData(Bundle data) {String mediaPath data…

python开课吧1980课程_开课吧的课程怎么样?

就那那些编程开发课来说。现在网络上充斥着大量的编程开发课程&#xff0c;什么python的&#xff0c;java的&#xff0c;c的&#xff0c;而且名字一个比一个夸张&#xff0c;21天精通c&#xff0c;7天熟练运用java&#xff0c;3天掌握python核心代码&#xff0c;这些课程标题简…

专业概念

1.JDBC: java数据库连接&#xff08;JDBC&#xff09;用于在java程序中实现数据库的操作功能&#xff0c;它提供了执行sql语句&#xff0c;访问各种数据库的方法&#xff0c;并为各种不同的数据库提供统一的操作接口&#xff0c;java.sql包中 包含了jdbc操作数据库的所有类 2.…

前端解决跨域问题的8种方案

2019独角兽企业重金招聘Python工程师标准>>> 1.同源策略如下&#xff1a; URL说明是否允许通信http://www.a.com/a.js http://www.a.com/b.js同一域名下允许http://www.a.com/lab/a.js http://www.a.com/script/b.js同一域名下不同文件夹允许http://www.a.com:8000/…

k歌的录音伴奏合成技术如何实现_K歌神器,用唱吧麦克风攀登天籁高峰

自从喜欢上了手机K歌&#xff0c;经常会上传一些自己的作品&#xff0c;起初无论音质如何都是乐在其中&#xff0c;可时间久了发现回放效果确实不如那榜单上的高手&#xff0c;究其原因想到了麦克风&#xff0c;网上一搜果然有各种K歌辅助工具&#xff0c;多番对比之下&#xf…

浅谈内存开辟问题和Block内存问题

我们知道&#xff0c;内存分为栈&#xff0c;堆&#xff0c;块。 栈中的内存由系统自己释放&#xff0c;堆是存对象初始化的地方&#xff0c;块是CPU与内存连接的缓冲器&#xff0c;运行速度比内存快&#xff0c;比CPU慢。 例如&#xff0c;我们NSMutableArray *array [NSMuta…

vue render函数_Vue原理解析(一):Vue到底是什么?

Vue&#xff0c;现在前端的当红炸子鸡&#xff0c;随着热度指数上升&#xff0c;实在是有必要从源码的角度&#xff0c;对它功能的实现原理一窥究竟。个人觉得看源码主要是看两样东西&#xff0c;从宏观上来说是它的设计思想和实现原理&#xff1b;微观上来说就是编程技巧&…

scrapy爬虫-setting.py

# Obey robots.txt rulesROBOTSTXT_OBEY False  不遵从网站的robots.txt法则 # See also autothrottle settings and docsDOWNLOAD_DELAY 3  每次下载延迟3秒&#xff0c;防止造成网站攻击 # Override the default request headers:DEFAULT_REQUEST_HEADERS { Accept:…

android点击左上角划出,使用Android中的Path和RectF在左上角右上角左下角绘制圆角...

有一个Path#addRoundRect()重载,它接受一个包含八个值的float数组,其中我们可以为四个角中的每一个指定x和y半径.这些值为[x,y]对,从左上角开始,顺时针绕其余部分.对于我们想要舍入的那些角,我们将该对的两个值都设置为半径值,并将它们保留为零,而不是那些.作为一个说明性示例,…

Nodejs微信开发

因为使用了Bot Framework开发了一个小功能&#xff0c;它目前支持了Skype\Teams\Slack等&#xff0c;但在国内来讲&#xff0c;微信还是一个比较流行的软件&#xff0c;所以需要接上微信 原来开发Bot的时候使用的是.Net开发的&#xff0c;这次我决定使用Nodejs开发一个简单的后…

性别有什么用_为啥不让男孩玩布娃娃?别让你的“性别偏见”,给孩子的人生设限...

在养育孩子的过程中&#xff0c;父母总是会犯许多错误&#xff0c;更是有一些错误会直接使孩子毁掉一生&#xff0c;而性别偏见正是很多家长都会去犯的错误&#xff0c;对男孩和女孩有着刻板印象&#xff0c;也正是因为这一点使孩子的潜力和天赋被压制。前几天我带着孩子去逛商…

android的时间代码怎么写,Android 日期和时间的使用实例详解

Android 日期和时间的使用日期和时间的使用&#xff1b;1&#xff1a;弹出框TimePickerDialog,DatePickerDialog2&#xff1a;组件TimePicker,DatePickerTimePickerDialog的使用&#xff1a;通过点击button显示图一&#xff0c;然后用户可以设置时间DatePickerDialog的使用只需…

andriod studio 查看项目依赖_Intellij IDEA 中如何查看maven项目中所有jar包的依赖关系图...

Maven 组件界面介绍如上图标注 1 所示&#xff0c;为常用的 Maven 工具栏&#xff0c;其中最常用的有&#xff1a;第一个按钮&#xff1a;Reimport All Maven Projects 表示根据 pom.xml 重新载入项目。一般单我们在 pom.xml 添加了依赖包或是插件的时候&#xff0c;发现标注 4…