之前在网上看到了当Slider控件在滑动时会弹出气泡指示器,觉得很有趣,于是就进行拓展,就有了下面介绍的一个安卓控件:IndicatorSeekBar。先附上IndicatorSeekBar项目地址。
1:先分享给我编写这个组件灵感的网址,感谢这个网站让我看到有趣的新东西:
滑动弹出气泡的slider组件:material.io/guidelines/…
附图:
part1: seekbar主体:细分为5个小部分:
- . 背景条
- . 进度条
- . 滑块
- . 刻度
- . 刻度的文字
part2: 指示器:采用弹出PopouWindow的方式实现。
实现 : 当点击seekbar时, 弹出PopouWindow ; 当滑动seekbar时, 不断更新 PopouWindow 的位置, 达到指示器移动的效果;当点击结束时,将指示器的PopouWindow dismiss掉。
4.主要代码
1.1 背景条:使用会之后线条的方式绘制。
- //绘制主体背景
- mStockPaint.setStrokeWidth(p.mBackgroundTrackSize);
- mStockPaint.setColor(p.mBackgroundTrackColor);
- canvas.drawLine(thumbX, mTrackY, mSeekEnd, mTrackY, mStockPaint);
1.2 进度条:绘制同背景条。
- //绘制主体进度
- mStockPaint.setStrokeWidth(p.mProgressTrackSize);
- canvas.drawLine(mSeekStart, mTrackY, thumbX, mTrackY, mStockPaint);
1.3 滑块:绘制圆。
- //绘制滑块
- canvas.drawCircle(thumbX + p.mBackgroundTrackSize / 2.0f, mTrackY, mIsTouching ? mThumbRadius: (2 * mThumbRadius / 3f), mStockPaint);
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);
1.5 刻度文字:绘制文本。
- //绘制刻度文字
- canvas.drawText(text, mTextLocationList.get(i), mPaddingTop + mThumbRadius * 2 + mRect.height() + IndicatorUtils.dp2px(mContext, 3), mTextPaint);
2.指示器:创建PopouWindow
2.1 创建
- mIndicator = new PopupWindow(mIndicatorView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, false);
2.2 弹出
- //监听seekbar的onTouch方法 ;当开始点击滑动时,弹出PopouWindow;
- mPopouWindow.showAsDropDown(mSeekBar, (int)(touchX - mIndicator.getContentView().getMeasuredWidth() / 2f), -(mSeekBar.getMeasuredHeight() + mIndicator.getContentView().getMeasuredHeight() + mSeekBar.getPaddingTop() + IndicatorUtils.dp2px(mContext, 2)));
2.3 更新位置
- //监听seekbar的onTouch方法 ;当滑动时,根据滑动的坐标更新PopouWindow的弹出位置;
- mPopouWindow.update(mSeekBar, (int)(touchX - mIndicator.getContentView().getMeasuredWidth() / 2), -(mSeekBar.getMeasuredHeight() + mIndicator.getContentView().getMeasuredHeight() + mSeekBar.getPaddingTop() + IndicatorUtils.dp2px(mContext, 2)), -1, -1);
2.3 消失
- //监听seekbar的onTouch方法 ;当触摸取消时,dismiss PopouWindow;
- mPopouWindow.dismiss();
上面的代码都不难,复杂的是内部的相互位置,不断加减计算出相关的坐标位置是指示器正确显示的关键:通过获得屏幕的宽度减去两边的padding来获得seekbar的宽度,再通过块数绘制获得一块block的长度,然后绘制刻度和刻度文字,根据触摸的坐标计算PopouWindow的位置,当进度改变时,更新其位置。
3.seekbar实现得到功能有哪些:
- 可以自定义尺寸和颜色
- 可以隐藏刻度
- seekbar选择圆角/方角
- 滑块下显示进度
- 自定义刻度下的文字
- 自定义滑块的图片
- 自定义刻度的图片
- 支持进度监听
文字不能对一些细节进行详细的描述,如果对此项目感兴趣,欢迎review代码交流。
欢迎评论交流。
来源: https://juejin.im/entry/59fe746251882561a209d948