一款美观的自定义SeekBar,支持单、双向、阶段滑动、刻度、负数等多种强大自定义属性

效果图

效果图


前言

篇幅有限,本文只讲解关键关键思路,伸手党和想看详细思路的请移步 传送门点我点我!!,如果喜欢,欢迎 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文件!

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
在Android中,可以通过自定义SeekBar实现数字滑动功能。首先,在布局文件中定义自定义SeekBar的样式,可以使用ProgressBar来实现。如下所示: ``` <ProgressBar android:id="@+id/customSeekBar" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:progressDrawable="@drawable/custom_seekbar_progress" android:thumb="@drawable/custom_seekbar_thumb" /> ``` 在drawable文件夹下创建custom_seekbar_progress.xml和custom_seekbar_thumb.xml来定义SeekBar的背景和滑块样式。在custom_seekbar_progress.xml中,可以使用shape和gradient标签来定义进度的背景样式。在custom_seekbar_thumb.xml中,可以使用shape标签来定义滑块的样式。 接下来,在Activity或Fragment中找到SeekBar的实例,并设置OnSeekBarChangeListener监听器。在监听器中,通过getProgress方法获取SeekBar的进度值,并根据需要进行相应的处理。例如,可以在TextView中显示SeekBar的进度值,如下所示: ``` SeekBar customSeekBar = findViewById(R.id.customSeekBar); final TextView progressTextView = findViewById(R.id.progressTextView); customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { progressTextView.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // 当开始滑动SeekBar时执行的操作 } @Override public void onStopTrackingTouch(SeekBar seekBar) { // 当结束滑动SeekBar时执行的操作 } }); ``` 通过设置OnSeekBarChangeListener监听器,可以在SeekBar滑动时实时更新进度值,并进行相应的处理操作。根据自己的需求,可以在onProgressChanged、onStartTrackingTouch和onStopTrackingTouch方法中添加自定义的逻辑。 以上就是使用自定义SeekBar实现数字滑动的简方法。可以根据自己的需求进行进一步的定制和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值