搜索自定义seekbar全都是基于原生seekbar都是拖动滑块的,并且点击seekbar某个位置就会跳变到那里,我想要的是跟miui10的那个亮度条那样滑动来调节的,既然没有那就自己动手吧。
首先自己要清楚要画出来的是什么样的,这里先看下效果图:
主要的就是要draw两个原件矩形,一个背景,一个进度的方块,然后通过onTouchEvent来触发滑动改变进度。
首先先声明两支笔,一只画背景,一只话进度,然后给笔设置颜色:
private Paint bgPaint;
private Paint barPaint;
public void init(){
bgPaint = new Paint();
barPaint = new Paint();
bgPaint.setAntiAlias(true);
barPaint.setAntiAlias(true);
bgPaint.setColor(Color.GRAY);
barPaint.setColor(Color.WHITE);
}
绘制方法里面画一下康康效果,可以看到已经成功一半了:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawRoundRect(0,0,width,height,10,10,bgPaint);
canvas.drawRoundRect(0,0,width/2f,height,10,10,barPaint);
}
接下来就是设置成动态的,接受进度值改变来修改进度,也就是上面第二个圆角矩形的宽度:
private int maxProgress = 100;
private int currentProgress = 50;
private float radius = 10;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawRoundRect(0f,0f,width,height,radius,radius,bgPaint);
float barWidth = width*1.0f/ maxProgress * currentProgress;
canvas.drawRoundRect(0,0,barWidth,height,radius,radius,barPaint);
}
当前进度、最大进度、圆角半径后面可以动态修改。
然后,我们来处理touch事件。
思路就是按下的时候记录当前进度以及当前按下的点的x轴的值,然后在滑动的时候去计算滑动的距离,用滑动距离 ÷ 控件宽度 = 滑动进度 ÷ 最大进度来得到滑动进度,再用记录的当前进度 + 滑动进度赋值给当前进度,再重新绘制一遍就ok了:
private float downX;
private int currentCountTemp;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
currentCountTemp = currentProgress;
return true;
case MotionEvent.ACTION_MOVE:
float downXTemp = event.getX();
float x = downXTemp - downX;
currentProgress = currentCountTemp + (int) (x/getWidth() * maxProgress);
if(currentProgress < 0){
currentProgress = 0;
}else if(currentProgress > maxProgress){
currentProgress = maxProgress;
}
invalidate();
return true;
default:
break;
}
return super.onTouchEvent(event);
}
public class MySeekBar extends View {
private String TAG = "MySeekBar";
private int maxProgress = 100;
private int currentProgress = 50;
private float radius = 10;
private Paint bgPaint;
private Paint barPaint;
public void setBgColor(int bgColor) {
bgPaint.setColor(bgColor);
}
public void setBarColor(int barColor) {
barPaint.setColor(barColor);
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
public int getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(int currentProgress) {
this.currentProgress = currentProgress;
}
public void setRadius(float radius) {
this.radius = radius;
}
public MySeekBar(Context context) {
super(context);
init();
}
public MySeekBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MySeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void init(){
bgPaint = new Paint();
barPaint = new Paint();
bgPaint.setAntiAlias(true);
barPaint.setAntiAlias(true);
bgPaint.setColor(Color.GRAY);
barPaint.setColor(Color.WHITE);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawRoundRect(0f,0f,width,height,radius,radius,bgPaint);
float barWidth = width*1.0f/ maxProgress * currentProgress;
canvas.drawRoundRect(0,0,barWidth,height,radius,radius,barPaint);
}
private float downX;
private int currentCountTemp;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
currentCountTemp = currentProgress;
Log.i(TAG, "onTouchEvent: downX:"+downX);
return true;
case MotionEvent.ACTION_MOVE:
float downXTemp = event.getX();
float x = downXTemp - downX;
currentProgress = currentCountTemp + (int) (x/getWidth() * maxProgress);
if(currentProgress < 0){
currentProgress = 0;
}else if(currentProgress > maxProgress){
currentProgress = maxProgress;
}
invalidate();
if(onDragListener != null){
onDragListener.onProgressChange(currentProgress);
}
return true;
default:
break;
}
return super.onTouchEvent(event);
}
public interface OnDragListener{
void onProgressChange(int progress);
}
private OnDragListener onDragListener;
public void setOnDragListener(OnDragListener onDragListener) {
this.onDragListener = onDragListener;
}
}