美文网首页
Android正负Seekbar

Android正负Seekbar

作者: 不会弹钢琴de大叔 | 来源:发表于2023-08-08 08:37 被阅读0次

    项目需要做了一个正负滑动的Seekbar

    public class CenterSeekBarView extends View {
        private static final String TAG = CenterSeekBarView.class.getSimpleName();
        private Paint mThumbPaint;
        private Paint mProgressPaint;
        private Paint mTextPaint;
        private Paint mThumbTextPaint;
        @ColorInt
        private int progressBackColor;
        @ColorInt
        private int progressColor;
        private int maxValue;
        private int minValue;
        private int measuredWidth;
        private int measuredHeight;
        private float thumbRadius;
        private int progressBarCoarse;
        private int viewPadding;
        private final float[] thumbPosition = new float[2];
        private float lastX;
        private float lastY;
        private boolean canMove;
    
        public CenterSeekBarView(Context context) {
            this(context, null);
            init();
        }
    
        public CenterSeekBarView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
            init();
        }
    
        public CenterSeekBarView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            mThumbPaint = new Paint();
            mThumbPaint.setAntiAlias(true);
            mThumbPaint.setStyle(Paint.Style.FILL);
            mThumbPaint.setColor(Color.parseColor("#303030"));
            mProgressPaint = new Paint();
            mProgressPaint.setAntiAlias(true);
            mProgressPaint.setStyle(Paint.Style.FILL);
            mTextPaint = new Paint();
            mTextPaint.setAntiAlias(true);
            mTextPaint.setStyle(Paint.Style.FILL);
            mTextPaint.setColor(Color.parseColor("#FFFFFF"));
            mThumbTextPaint = new Paint();
            mThumbTextPaint.setAntiAlias(true);
            mThumbTextPaint.setStyle(Paint.Style.FILL);
            mThumbTextPaint.setColor(Color.parseColor("#FFFFFF"));
    
            progressBackColor = Color.parseColor("#C2C2C2");
            progressColor = Color.parseColor("#C79C5B");
            thumbRadius = dip2px(20);
            progressBarCoarse = dip2px(10);
            viewPadding = dip2px(40);
            maxValue = 10;
            minValue = -10;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            measuredWidth = getMeasuredWidth();
            measuredHeight = getMeasuredHeight();
            float x = measuredWidth / 2f;
            float y = measuredHeight / 2f;
            thumbPosition[0] = x;
            thumbPosition[1] = y;
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            drawProgressBackground(canvas);
            drawProgressBar(canvas);
            drawThumb(canvas);
            drawText(canvas);
        }
    
        private void drawProgressBar(Canvas canvas) {
            float left = measuredWidth / 2f;
            float top = measuredHeight / 2f - progressBarCoarse / 2f;
            float right = thumbPosition[0];
            float bottom = measuredHeight / 2f + progressBarCoarse / 2f;
            mProgressPaint.setColor(progressColor);
            canvas.drawRoundRect(left, top, right, bottom, 5, 5, mProgressPaint);
        }
    
        private void drawProgressBackground(Canvas canvas) {
            float left = viewPadding;
            float top = measuredHeight / 2f - progressBarCoarse / 2f;
            float right = measuredWidth - viewPadding;
            float bottom = measuredHeight / 2f + progressBarCoarse / 2f;
            mProgressPaint.setColor(progressBackColor);
            canvas.drawRoundRect(left, top, right, bottom, 5, 5, mProgressPaint);
        }
    
        private void drawThumb(Canvas canvas) {
            canvas.drawCircle(thumbPosition[0], thumbPosition[1], thumbRadius, mThumbPaint);
            mThumbTextPaint.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(getPercent(), thumbPosition[0], thumbPosition[1] - thumbRadius - dip2px(10), mThumbTextPaint);
        }
    
        private void drawText(Canvas canvas) {
            float y = measuredHeight / 2f + progressBarCoarse / 2f + dip2px(20);
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            canvas.drawText(minValue + "km/h", viewPadding, y, mTextPaint);
            mTextPaint.setTextAlign(Paint.Align.RIGHT);
            canvas.drawText(maxValue + "km/h", measuredWidth - viewPadding, y, mTextPaint);
        }
    
        private String getPercent() {
            float total = measuredWidth / 2f - viewPadding;
            float current = Math.abs(thumbPosition[0] - measuredWidth / 2f);
            float percent = current / total;
            Log.d(TAG, "getPercent: " + total + "," + current + "<" + percent);
            if (thumbPosition[0] < measuredWidth / 2f) {
                return "" + (int) (percent * minValue);
            }
            return (int) (percent * maxValue) + "";
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (!isEnabled()) {
                Log.d(TAG, "onTouchEvent: enable false");
                return false;
            }
            int x = (int) event.getRawX();
            int y = (int) event.getRawY();
            float px = event.getX();
            float py = event.getY();
            int dealtX = 0;
            int dealtY = 0;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    getParent().requestDisallowInterceptTouchEvent(true);
                    canMove = checkInThumb(px, py);
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(TAG, "onTouchEvent: move");
                    dealtX += Math.abs(x - lastX);
                    dealtY += Math.abs(y - lastY);
                    // 这里是拦截判断依据是左右上下滑动,水平进行滑动,自己消费,请求父类ViewPage不拦截;竖直方向滑动,交给父类Scrollview
                    getParent().requestDisallowInterceptTouchEvent(dealtX >= dealtY);
                    lastX = x;
                    lastY = y;
                    setMovePosition(px);
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:
                    Log.d(TAG, "onTouchEvent: up");
                    canMove = false;
                    setMovePosition(px);
                    getParent().requestDisallowInterceptTouchEvent(false);
                    break;
                default:
                    break;
            }
            return true;
        }
    
        private void setMovePosition(float px) {
            if (px > measuredWidth - viewPadding) {
                px = measuredWidth - viewPadding;
            } else if (px < viewPadding) {
                px = viewPadding;
            }
    //        float tempX = checkIntPosition(px);
    //        if (tempX > measuredWidth - viewPadding) {
    //            tempX = measuredWidth - viewPadding;
    //        } else if (tempX < viewPadding) {
    //            tempX = viewPadding;
    //        }
            thumbPosition[0] = px;
            postInvalidate();
        }
    
        private float checkIntPosition(float x) {
            float total = measuredWidth / 2f - viewPadding;
            float current = Math.abs(x - measuredWidth / 2f);
            float percent = current / total;
            boolean isLeft = x < measuredWidth / 2f;
            if (isLeft) {
                float flMin = percent * minValue;
                BigDecimal bigDecimal = new BigDecimal(flMin);
                bigDecimal = bigDecimal.setScale(1, RoundingMode.HALF_UP);
                float px = bigDecimal.floatValue() / minValue * measuredWidth / 2f;
                return measuredWidth / 2f - px;
            } else {
                float flMax = percent * maxValue;
                BigDecimal bigDecimal = new BigDecimal(flMax);
                bigDecimal = bigDecimal.setScale(1, RoundingMode.HALF_UP);
                float px = bigDecimal.floatValue() / maxValue * (measuredWidth / 2f);
                return px + measuredWidth / 2f;
            }
        }
    
        public void setMaxValue(int maxValue) {
            this.maxValue = maxValue;
        }
    
        public void setMinValue(int minValue) {
            this.minValue = minValue;
        }
    
        public void setThumbRadius(int thumbRadius) {
            this.thumbRadius = thumbRadius;
        }
    
        private boolean checkInThumb(float x, float y) {
            return checkPosition(thumbPosition[0], thumbPosition[1], thumbRadius * 2, x, y);
        }
    
        /**
         * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
         */
        private int dip2px(float dpValue) {
            final float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        /**
         * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
         */
        private int px2dip(float pxValue) {
            final float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (pxValue / scale + 0.5f);
        }
    
        public void setEnable(boolean enable) {
            setEnabled(enable);
        }
    
        /**
         * 判断坐标是否在指定范围内
         *
         * @param targetX 目标x
         * @param targetY 目标y
         * @param size    尺寸
         * @param x       x
         * @param y       y
         * @return
         */
        private boolean checkPosition(float targetX, float targetY, float size, float x, float y) {
            float distanceX = Math.abs(targetX + size / 2 - x);
            float distanceY = Math.abs(targetY + size / 2 - y);
            double distanceZ = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2));
            return distanceZ < size / 2;
        }
    
        /**
         * 判断浮点类型数据是不是整数,整数去除小数点
         *
         * @param d double类型数据
         * @return string数据
         */
        public static String doubleTrans(float d) {
            if (Math.round(d) - d == 0) {
                return String.valueOf((long) d);
            }
            return String.valueOf(d);
        }
    

    相关文章

      网友评论

          本文标题:Android正负Seekbar

          本文链接:https://www.haomeiwen.com/subject/qzygpdtx.html