一款美观的自定义SeekBar,支持单、双向、阶段滑动、刻度、负数等多种强大自定义属性
来源:互联网 发布:分析师软件徐小明 编辑:程序博客网 时间:2024/05/16 07:46
效果图
前言
篇幅有限,本文只讲解关键关键思路,伸手党和想看详细思路的请移步 传送门点我点我!!,如果喜欢,欢迎 Star 和 Fork !
实现思路
本控件其实奔着双向滑动的SeekBar实现的,不过兼容了单向滑动(隐藏一个拖动按钮不就是单向的了嘛),所以我以 双向滑动思路为例。
RangeSeekBar主要包括两个类,一个是RangeSeekbar类,主要负责绘制进度条以及处理滑动相关逻辑,计算当前滑动值;另一个是SeekBar类,主要负责绘制拖动按钮相关,如绘制背景以及提示信息等。我们用RangeSeekBar初始化控件的一些属性,并且生成两个SeekBar对象,协调他们之间的关系。
关键代码及解析
主要包括控件绘制、两个拖动按钮的滑动逻辑及进度的计算。
控件绘制
绘制原理很简单,计算 –> 定位 –> 绘制。讲之前先放一张图,你就能理解Android是如何定位的了。
绘制进度条
计算:
lineLeft = 2 * DEFALT_PADDING;lineRight = View的宽度 - 2 * DEFALT_PADDING;lineTop = (int)mHintBGHeight+ mThumbSize/2 -mSeekbarHight/2 + DEFALT_PADDING;lineBottom = lineTop + mSeekbarHight;lineWidth = lineRight - lineLeft;lineCorners = (int) ((lineBottom - lineTop) * 0.45f);
定位:
RectF line = new RectF();line.set(lineLeft, lineTop, lineRight, lineBottom);
绘制:
canvas.drawRoundRect(line, lineCorners, lineCorners, mMainPaint);
绘制拖动条按钮
这里只讲解使用图片如何绘制,自己填充的和进度条类似。
计算:
left = lineLeft - mThumbSize / 2; right = lineLeft + mThumbSize / 2; top = lineBottom - mThumbSize / 2; bottom = lineBottom + mThumbSize / 2; Bitmap original = BitmapFactory.decodeResource(context.getResources(), bmpResId); if (original != null) { Matrix matrix = new Matrix(); float scaleHeight = mThumbSize * 1.0f / original.getHeight(); float scaleWidth = scaleHeight; matrix.postScale(scaleWidth, scaleHeight); bmp = Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true); }
定位与绘制:
canvas.drawBitmap(bmp, left, lineTop - bmp.getHeight() / 2, null);
两个拖动按钮的滑动逻辑及进度的计算
首先要判断当前手指拖动的是哪个按钮,SeekBar类中这个方法可以判断当前按钮是否被拖动:
/** * 拖动检测 * @param event * @return */ protected boolean collide(MotionEvent event) { float x = event.getX(); float y = event.getY(); int offset = (int) (lineWidth * currPercent); return x > left + offset && x < right + offset && y > top && y < bottom; }
然后在RangeSeekbar的onTouchEvent中当手指按下时根据按钮的位置和手指的当前坐标即可判断当前按钮
case MotionEvent.ACTION_DOWN: boolean touchResult = false; if (rightSB != null && rightSB.currPercent >= 1 && leftSB.collide(event)) { currTouch = leftSB; touchResult = true; } else if (rightSB != null && rightSB.collide(event)) { currTouch = rightSB; touchResult = true; } else if (leftSB.collide(event)) { currTouch = leftSB; touchResult = true; }
当手指移动时,我们根据坐标即可计算出按钮当前位置占整个进度条的比例,从而可以算出两个按钮的值,至于两个按钮相遇时,我们可以根据两个按钮当前的值判断,左边的按钮的值不能大于右边的值,同理,右边按钮的值也不能小于左边的值。
注意
进度提示的背景的绘制和拖动的按钮原理类似,但是有一点不一样的地方就是考虑到他可能会被拉伸,所以我用的是9Path文件,9Path的绘制和普通的bitmap绘制稍有不同,详情请看另一篇文章 9path 绘制。如果你想改变它的背景图片的话,请使用9Path文件!
- 一款美观的自定义SeekBar,支持单、双向、阶段滑动、刻度、负数等多种强大自定义属性
- 自定义双向滑动SeekBar
- 自定义带刻度的seekbar
- 简单的自定义 刻度seekbar?
- 自定义带刻度的SeekBar
- Android 自定义双向滑动SeekBar
- Android_自定义双向SeekBar
- Android自定义正负双向SeekBar
- Android自定义SeekBar滑动条
- Android——自定义带刻度的SeekBar单向拖动条
- 美观的自定义选择标签FlowLayout外加支持左中右对齐及滚动等功能_图文加源码
- HorizontalNumberView与seekbar共享滑动的自定义view
- 实现滑动选择价格区间的自定义seekbar
- android SeekBar自定义样式滑动条的使用
- 自定义SeekBar使用双向滑块选择
- SeekBar 的自定义样式
- 自定义竖着的SeekBar
- 自定义风格的SeekBar
- Activiti工作流(1)
- Android Activity的启动机制流程和四种启动模式
- PopupWindow 布局文件的两种写法
- Redis 事务
- 前后端分离趋势谈
- 一款美观的自定义SeekBar,支持单、双向、阶段滑动、刻度、负数等多种强大自定义属性
- 并发控制与事务
- 图片存储
- Error:Module 'xxxx' production: java.lang.NullPointerException
- java强行删除文件(针对进程正在使用的文件的删除)
- linux常用命令
- Linux 检查是否安装perl模块及列出所有已安装的perl模块(安装路径、版本号)
- MFC控制台输出
- 在Android代码示例中插入新联系人