@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled())
            return false;

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (radiusAnimator != null)
                radiusAnimator.end();
            radiusAnimator = ValueAnimator.ofFloat(thumbRadius, THUMB_RADIUS_DRAGGED);
            radiusAnimator.setDuration(200);
            radiusAnimator.setInterpolator(interpolator);
            radiusAnimator.addUpdateListener(animation -> {
                thumbRadius = (float) animation.getAnimatedValue();
                postInvalidate();
            });
            radiusAnimator.start();
            ViewParent parent = getParent();
            if (parent != null)
                parent.requestDisallowInterceptTouchEvent(true);
            if (showLabel)
                popup.show(this);
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
            if (style == Style.Discrete) {
                float val = (float) Math.floor((value - min + step / 2) / step) * step + min;
                if (valueAnimator != null)
                    valueAnimator.cancel();
                valueAnimator = ValueAnimator.ofFloat(value, val);
                valueAnimator.setDuration(200);
                valueAnimator.setInterpolator(interpolator);
                valueAnimator.addUpdateListener(animation -> {
                    value = (float) animation.getAnimatedValue();
                    int thumbX = (int) ((value - min) / (max - min) * (getWidth() - getPaddingLeft() - getPaddingRight()) + getPaddingLeft());
                    int thumbY = getHeight() / 2;
                    int radius = rippleDrawable.getRadius();
                    rippleDrawable.setBounds(thumbX - radius, thumbY - radius, thumbX + radius, thumbY + radius);
                    postInvalidate();
                });
                valueAnimator.start();
            }
            if (radiusAnimator != null)
                radiusAnimator.end();
            radiusAnimator = ValueAnimator.ofFloat(thumbRadius, THUMB_RADIUS);
            radiusAnimator.setDuration(200);
            radiusAnimator.setInterpolator(interpolator);
            radiusAnimator.addUpdateListener(animation -> {
                thumbRadius = (float) animation.getAnimatedValue();
                postInvalidate();
            });
            radiusAnimator.start();
            ViewParent parent = getParent();
            if (parent != null)
                parent.requestDisallowInterceptTouchEvent(false);
            if (showLabel)
                popup.dismiss();
        }

        float v = (event.getX() - getPaddingLeft()) / (getWidth() - getPaddingLeft() - getPaddingRight());
        v = Math.max(0, Math.min(v, 1));
        float newValue = v * (max - min) + min;

        int thumbX = (int) (v * (getWidth() - getPaddingLeft() - getPaddingRight()) + getPaddingLeft());
        int thumbY = getHeight() / 2;
        int radius = rippleDrawable.getRadius();

        if (showLabel) {
            int[] location = new int[2];
            getLocationInWindow(location);
            popup.setText(String.format(labelFormat, newValue));
            popup.update(thumbX + location[0] - popup.getBubbleWidth() / 2, thumbY - radius + location[1] - popup.getHeight());
        }

        if (rippleDrawable != null) {
            rippleDrawable.setHotspot(event.getX(), event.getY());
            rippleDrawable.setBounds(thumbX - radius, thumbY - radius, thumbX + radius, thumbY + radius);
        }

        postInvalidate();
        if (newValue != value && onValueChangedListener != null) {
            if (style == Style.Discrete) {
                int sv = stepValue(newValue);
                if (stepValue(value) != sv)
                    onValueChangedListener.onValueChanged(this, sv);
            } else {
                onValueChangedListener.onValueChanged(this, newValue);
            }
        }
        value = newValue;
        super.onTouchEvent(event);
        return true;
    }
@ Override public boolean onTouchEvent ( MotionEvent event ) { if ( ! isEnabled ( ) ) return false ; if ( event . getAction ( ) == MotionEvent . ACTION_DOWN ) { if ( radiusAnimator != null ) radiusAnimator . end ( ) ; radiusAnimator = ValueAnimator . ofFloat ( thumbRadius , THUMB_RADIUS_DRAGGED ) ; radiusAnimator . setDuration ( 200 ) ; radiusAnimator . setInterpolator ( interpolator ) ; radiusAnimator . addUpdateListener ( animation -> { thumbRadius = ( float ) animation . getAnimatedValue ( ) ; postInvalidate ( ) ; } ) ; radiusAnimator . start ( ) ; ViewParent parent = getParent ( ) ; if ( parent != null ) parent . requestDisallowInterceptTouchEvent ( true ) ; if ( showLabel ) popup . show ( this ) ; } else if ( event . getAction ( ) == MotionEvent . ACTION_CANCEL || event . getAction ( ) == MotionEvent . ACTION_UP ) { if ( style == Style . Discrete ) { float val = ( float ) Math . floor ( ( value - min + step / 2 ) / step ) * step + min ; if ( valueAnimator != null ) valueAnimator . cancel ( ) ; valueAnimator = ValueAnimator . ofFloat ( value , val ) ; valueAnimator . setDuration ( 200 ) ; valueAnimator . setInterpolator ( interpolator ) ; valueAnimator . addUpdateListener ( animation -> { value = ( float ) animation . getAnimatedValue ( ) ; int thumbX = ( int ) ( ( value - min ) / ( max - min ) * ( getWidth ( ) - getPaddingLeft ( ) - getPaddingRight ( ) ) + getPaddingLeft ( ) ) ; int thumbY = getHeight ( ) / 2 ; int radius = rippleDrawable . getRadius ( ) ; rippleDrawable . setBounds ( thumbX - radius , thumbY - radius , thumbX + radius , thumbY + radius ) ; postInvalidate ( ) ; } ) ; valueAnimator . start ( ) ; } if ( radiusAnimator != null ) radiusAnimator . end ( ) ; radiusAnimator = ValueAnimator . ofFloat ( thumbRadius , THUMB_RADIUS ) ; radiusAnimator . setDuration ( 200 ) ; radiusAnimator . setInterpolator ( interpolator ) ; radiusAnimator . addUpdateListener ( animation -> { thumbRadius = ( float ) animation . getAnimatedValue ( ) ; postInvalidate ( ) ; } ) ; radiusAnimator . start ( ) ; ViewParent parent = getParent ( ) ; if ( parent != null ) parent . requestDisallowInterceptTouchEvent ( false ) ; if ( showLabel ) popup . dismiss ( ) ; } float v = ( event . getX ( ) - getPaddingLeft ( ) ) / ( getWidth ( ) - getPaddingLeft ( ) - getPaddingRight ( ) ) ; v = Math . max ( 0 , Math . min ( v , 1 ) ) ; float newValue = v * ( max - min ) + min ; int thumbX = ( int ) ( v * ( getWidth ( ) - getPaddingLeft ( ) - getPaddingRight ( ) ) + getPaddingLeft ( ) ) ; int thumbY = getHeight ( ) / 2 ; int radius = rippleDrawable . getRadius ( ) ; if ( showLabel ) { int [ ] location = new int [ 2 ] ; getLocationInWindow ( location ) ; popup . setText ( String . format ( labelFormat , newValue ) ) ; popup . update ( thumbX + location [ 0 ] - popup . getBubbleWidth ( ) / 2 , thumbY - radius + location [ 1 ] - popup . getHeight ( ) ) ; } if ( rippleDrawable != null ) { rippleDrawable . setHotspot ( event . getX ( ) , event . getY ( ) ) ; rippleDrawable . setBounds ( thumbX - radius , thumbY - radius , thumbX + radius , thumbY + radius ) ; } postInvalidate ( ) ; if ( newValue != value && onValueChangedListener != null ) { if ( style == Style . Discrete ) { int sv = stepValue ( newValue ) ; if ( stepValue ( value ) != sv ) onValueChangedListener . onValueChanged ( this , sv ) ; } else { onValueChangedListener . onValueChanged ( this , newValue ) ; } } value = newValue ; super . onTouchEvent ( event ) ; return true ; }
-------------------------------