IndicatorSeekBar Android自定义SeekB

作者: warkiz | 来源:发表于2017-11-04 21:10 被阅读1690次

    本文项目地址:https://github.com/warkiz/IndicatorSeekBar

    控件使用姿势:http://www.jianshu.com/p/beb19f770e68

    overview.png

    之前在网上看到了当Slider控件在滑动时会弹出气泡指示器,觉得很有趣,于是就进行拓展,就有了下面介绍的一个安卓控件:IndicatorSeekBar。先附上IndicatorSeekBar项目地址: GitHub: https://github.com/warkiz/IndicatorSeekBar

    1:先分享给我编写这个组件灵感的网址,感谢这个网站让我看到有趣的新东西:
    滑动弹出气泡的slider组件:https://material.io/guidelines/components/sliders.html#sliders-continuous-slider
    附图:

    image.png
    1. 对于IndicatorSeekBar,虽然做不了和上面网站的一模一样,但是基本功能还是具备的。先上笔者实现的效果图:


      indicator_normal.gif
      indicator_custom.gif
    2. SeekBar实现的功能有哪些:

      • 可以自定义尺寸和颜色
      • 可以隐藏刻度
      • SeekBar选择圆角/方角
      • 滑块下显示进度
      • 自定义刻度下的文字
      • 自定义滑块的图片
      • 自定义刻度的图片
      • 自定义气泡指示器
      • 支持进度监听
      • ......
    1. 实现思路: 笔者将Slider分为2大部分:上半部分的指示器和下半部分的SeekBar主体 , 如图 :


      image.png

    Part1:SeekBar主体:细分为5个小部分:

    • 背景条 track_background_bar
    • 进度条 track_progress_bar
    • 滑块 thumb
    • 刻度 tick
    • 刻度的文字 text

    Part2: 指示器:弹出PopouWindow。

    实现 : 当点击seekbar时, 弹出PopouWindow ; 当滑动seekbar时, 不断更新
    PopouWindow 的位置, 达到指示器移动的效果;当点击结束时,将指示器的PopouWindow dismiss掉。

    5.主要代码

    5.1. 主体

    5.1.1 背景条:使用绘制线条的方式绘制。

    //绘制主体背景
    mStockPaint.setStrokeWidth(p.mBackgroundTrackSize);
    mStockPaint.setColor(p.mBackgroundTrackColor);
    canvas.drawLine(thumbX, mTrackY, mSeekEnd, mTrackY, mStockPaint);
    

    5.1.2 进度条:绘制同背景条。

    //绘制主体进度
    mStockPaint.setStrokeWidth(p.mProgressTrackSize);
    canvas.drawLine(mSeekStart, mTrackY, thumbX, mTrackY, mStockPaint);
    

    5.1.3 滑块:绘制圆。

    //绘制滑块
    canvas.drawCircle(thumbX + p.mBackgroundTrackSize / 2.0f, mTrackY, mIsTouching ? mThumbRadius : (2 * mThumbRadius / 3f), mStockPaint);
    

    5.1.4 刻度:绘制圆或者长方形。

    //绘制刻度
    canvas.drawCircle(locationX, mTrackY, mTickRadius, mStockPaint);
    or
    canvas.drawRect(locationX - IndicatorUtils.dp2px(mContext, 1), mTrackY - rectTickHeightRange / 2.0f, locationX + IndicatorUtils.dp2px(mContext, 1), mTrackY + rectTickHeightRange / 2.0f + .5f, mStockPaint);
    

    5.1.5 刻度文字:绘制文本。

    //绘制刻度文字
    canvas.drawText(text, mTextLocationList.get(i), mPaddingTop + mThumbRadius * 2 + mRect.height() + IndicatorUtils.dp2px(mContext, 3), mTextPaint);
    

    5.2.指示器:创建PopouWindow

    5.2.1 创建

        mIndicator = new PopupWindow(mIndicatorView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, false);
    

    5.2.2 弹出

    //监听SeekbBar的onTouch方法 ;当开始点击滑动时,弹出PopouWindow;
    mIndicator.showAsDropDown(mSeekBar, (int) (touchX - mIndicator.getContentView().getMeasuredWidth() / 2f), -(mSeekBar.getMeasuredHeight() + mIndicator.getContentView().getMeasuredHeight() + mSeekBar.getPaddingTop() +  IndicatorUtils.dp2px(mContext, 2)));
    

    5.2.3 更新位置

    //监听seekbar的onTouch方法 ;当滑动时,根据滑动的坐标更新PopouWindow的弹出位置;
     mIndicator.update(mSeekBar, (int) (touchX - mIndicator.getContentView().getMeasuredWidth() / 2), -(mSeekBar.getMeasuredHeight() + mIndicator.getContentView().getMeasuredHeight() + mSeekBar.getPaddingTop() +  IndicatorUtils.dp2px(mContext, 2)), -1, -1);
    

    5.2.4 消失

    //监听SeekBar的onTouch方法 ;当触摸取消时,dismiss PopouWindow;
     mIndicator.dismiss();
    

    上面的代码都不难,复杂的是内部的相互位置,不断加减计算出相关的坐标位置是指示器正确显示的关键:通过获得屏幕的宽度减去两边的padding来获得seekbar的宽度,再通过块数绘制获得一块block的长度,然后绘制刻度和刻度文字,根据触摸的坐标计算PopouWindow的位置,当进度改变时,更新其位置。

    文字不能对一些细节进行详细的描述,如果对此项目感兴趣,欢迎review代码交流。

    GitHub地址 https://github.com/warkiz/IndicatorSeekBar

    IndicatorSeekBar的实现思路已经介绍完了,如果想了解其使用场景与方式,请关注下一篇文章。

    IndicatorSeekBar的使用方式:http://www.jianshu.com/p/beb19f770e68

    感谢

    material.io-slider.

    MaterialDesignLibrary.

    PointerPopupWindow.

    SeekBarCompat.

    BubbleSeekBar.

    NumberProgressBar.

    android-slidr.

    RangeSeekBar.

    BubblePopupWindow.

    相关文章

      网友评论

      • 罗曼龍少爺:请问能否在continunos类型时显示刻度出tick?
      • 帅气熊熊熊:如何获取指示器里面view的id呢,我想通过监听滑动按钮来改变文字上面的文字
        帅气熊熊熊:我试了 获取不到id 直接报空指针
        帅气熊熊熊:方便加下你的微信或者qq吗
        warkiz:@帅气熊熊熊 你用的是哪个Indicator type? 如果是矩形的或者圆角矩形的,可以setCustomTopContentView设置一个textview,然后这个id你可以随便了
      • warkiz:欢迎吐槽😀

      本文标题:IndicatorSeekBar Android自定义SeekB

      本文链接:https://www.haomeiwen.com/subject/sfcqmxtx.html