之前在網(wǎng)上看到了當Slider控件在滑動時會彈出氣泡指示器,覺得很有趣,于是就進行拓展毕贼,就有了下面介紹的一個安卓控件:IndicatorSeekBar笛洛。先附上IndicatorSeekBar項目地址: GitHub: https://github.com/warkiz/IndicatorSeekBar
1:先分享給我編寫這個組件靈感的網(wǎng)址畅蹂,感謝這個網(wǎng)站讓我看到有趣的新東西:
滑動彈出氣泡的slider組件:https://material.io/guidelines/components/sliders.html#sliders-continuous-slider
附圖:
-
對于IndicatorSeekBar,雖然做不了和上面網(wǎng)站的一模一樣端圈,但是基本功能還是具備的焦读。先上筆者實現(xiàn)的效果圖:
-
SeekBar實現(xiàn)的功能有哪些:
- 可以自定義尺寸和顏色
- 可以隱藏刻度
- SeekBar選擇圓角/方角
- 滑塊下顯示進度
- 自定義刻度下的文字
- 自定義滑塊的圖片
- 自定義刻度的圖片
- 自定義氣泡指示器
- 支持進度監(jiān)聽
- ......
-
實現(xiàn)思路: 筆者將Slider分為2大部分:上半部分的指示器和下半部分的SeekBar主體 , 如圖 :
Part1:SeekBar主體:細分為5個小部分:
- 背景條 track_background_bar
- 進度條 track_progress_bar
- 滑塊 thumb
- 刻度 tick
- 刻度的文字 text
Part2: 指示器:彈出PopouWindow舱权。
實現(xiàn) : 當點擊seekbar時, 彈出PopouWindow 仑嗅; 當滑動seekbar時宴倍, 不斷更新
PopouWindow 的位置张症, 達到指示器移動的效果;當點擊結(jié)束時鸵贬,將指示器的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.指示器:創(chuàng)建PopouWindow
5.2.1 創(chuàng)建
mIndicator = new PopupWindow(mIndicatorView, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, false);
5.2.2 彈出
//監(jiān)聽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 更新位置
//監(jiān)聽seekbar的onTouch方法 畏铆;當滑動時,根據(jù)滑動的坐標更新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 消失
//監(jiān)聽SeekBar的onTouch方法 辞居;當觸摸取消時,dismiss PopouWindow蛋勺;
mIndicator.dismiss();
上面的代碼都不難瓦灶,復雜的是內(nèi)部的相互位置,不斷加減計算出相關(guān)的坐標位置是指示器正確顯示的關(guān)鍵:通過獲得屏幕的寬度減去兩邊的padding來獲得seekbar的寬度抱完,再通過塊數(shù)繪制獲得一塊block的長度贼陶,然后繪制刻度和刻度文字,根據(jù)觸摸的坐標計算PopouWindow的位置乾蛤,當進度改變時每界,更新其位置。
文字不能對一些細節(jié)進行詳細的描述家卖,如果對此項目感興趣眨层,歡迎review代碼交流。
IndicatorSeekBar的實現(xiàn)思路已經(jīng)介紹完了上荡,如果想了解其使用場景與方式趴樱,請關(guān)注下一篇文章。
IndicatorSeekBar的使用方式:http://www.reibang.com/p/beb19f770e68