一、前言:
SeekBar控件在开发中还是比较常见的,比如音视频进度、音量调节等,但是原生控件有时还不能满足我们的需求,今天就来学习一下如何自定义SeekBar控件,本文主要实现了一个带文字指示器效果的SeekBar控件,看下最终效果:

图片.png
二、实现
1、TextThumbSeekBar
@SuppressLint("AppCompatCustomView")
public class TextThumbSeekBar extends SeekBar {
// 画笔
private Paint mPaint;
// 进度文字位置信息
private Rect mProgressTextRect = new Rect();
// 滑块按钮宽度
private int mThumbWidth = dp2px(50);
private int mSeekBarMin;
public TextThumbSeekBar(Context context) {
this(context, null);
}
public TextThumbSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.seekBarStyle);
initData();
}
private void initData() {
mPaint = new TextPaint();
mPaint.setAntiAlias(true);
mPaint.setColor(BaseApplication.getInstance().getResources().getColor(R.color.color_FFFFFF));
mPaint.setTextSize(sp2px(16));
// 如果不设置padding,当滑动到最左边或最右边时,滑块会显示不全
setPadding(mThumbWidth / 2, 0, mThumbWidth / 2, 0);
}
public TextThumbSeekBar(Context context,AttributeSet attrs,int defStyleAttr){
super(context,attrs,defStyleAttr);
initData();
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 进度文字位置信息
String progressText = "+"+getProgress();
mPaint.getTextBounds(progressText, 0, progressText.length(), mProgressTextRect);
// 进度百分比
float progressRatio = (float) getProgress() / getMax();
// thumb偏移量
float thumbOffset = (mThumbWidth - mProgressTextRect.width()) / 2 - mThumbWidth * progressRatio;
float thumbX = getWidth() * progressRatio + thumbOffset;
//这里修改文字的范围,上或下
float thumbY = getHeight() / 2f - mProgressTextRect.height() / 2f-dp2px(8);
canvas.drawText(progressText, thumbX, thumbY, mPaint);
}
public void setMix(int min){
mSeekBarMin=min;
}
/**
* dp转px
*
* @param dp dp值
* @return px值
*/
public int dp2px(float dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getResources().getDisplayMetrics());
}
/**
* sp转px
*
* @param sp sp值
* @return px值
*/
private int sp2px(float sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
getResources().getDisplayMetrics());
}
}
2、布局
<RelativeLayout
android:id="@+id/rl_adjust"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_65">
<com.sumansoul.slim.tea.ui.view.TextThumbSeekBar
android:id="@+id/seek_progress"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_60"
android:max="100"
android:maxHeight="@dimen/dp_5"
android:progressDrawable="@drawable/seek_bar_white_bg"
android:thumb="@drawable/c_seekbar"
android:progress="50"
android:splitTrack="false"
android:layout_marginRight="@dimen/dp_12"
android:layout_marginLeft="@dimen/dp_12"
android:layout_centerVertical="true"
/>
</RelativeLayout>
3、背景seek_bar_white_bg
seek_bar_white_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--背景部分 -->
<item android:id="@android:id/background" >
<shape>
<solid android:color="#66ffffff"/>
<corners android:radius="@dimen/dp_3" />
</shape>
</item>
<!--progressBar部分(放下面) -->
<item android:id="@android:id/progress" >
<clip>
<shape>
<solid android:color="@color/color_FF876DAE" />
<corners android:radius="@dimen/dp_3" />
</shape>
</clip>
</item>
</layer-list>
4、c_seekbar
就是滑动的图片
5、seekBar使用:
(1)监听
SeekBar可以监听进度条拖拽的状态,代码如下:
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
1、当拖拽开始时,执行onStartTrackingTouch方法,且只会执行一次;
2、当拖拽结束时,执行onStopTrackingTouch方法,且只会执行一次;
3、当正在拖拽时,执行onProgressChanged方法,进度每次变化都会执行onProgressChanged方法,参数progress表示当前进度。
三、解析
1、最重要的
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 进度文字位置信息
String progressText = "+"+getProgress();
mPaint.getTextBounds(progressText, 0, progressText.length(), mProgressTextRect);
// 进度百分比
float progressRatio = (float) getProgress() / getMax();
// thumb偏移量
float thumbOffset = (mThumbWidth - mProgressTextRect.width()) / 2 - mThumbWidth * progressRatio;
float thumbX = getWidth() * progressRatio + thumbOffset;
//文字在seekBar上方,跟随seekBar滑动
//float thumbY = getHeight() / 2f - mProgressTextRect.height() / 2f-dp2px(8);
//文字在seekBar正中间,跟随seekBar滑动
float thumbY = getHeight() / 2f + mProgressTextRect.height() / 2f;
canvas.drawText(progressText, thumbX, thumbY, mPaint);
}
**注意: TextThumbSeekBar必须在xml指定高度,不然可能会不显示。
android:layout_height="@dimen/dp_60"
2、自定义SeekBar thumb透明效果
修改前:

图片.png
修改后:

图片.png
<!-- 是否设置一个间隙,让滑块与底部图片分隔 -->
android:splitTrack="false"
