自定义view之自定义滑动seekbar

搜索自定义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);
    }

最后再放出全部代码,xml声明属性就懒得搞了,可以自己去搞一下:

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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35584878/article/details/119893357