/** Handles thumb selection and movement. Notifies listener callback on certain events. */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: pressedThumb = evalPressedThumb(event.getX()); invalidate(); break; case MotionEvent.ACTION_MOVE: if (pressedThumb != null) { if (Thumb.MIN.equals(pressedThumb)) { setNormalizedMinValue(screenToNormalized(event.getX())); } else if (Thumb.MAX.equals(pressedThumb)) { setNormalizedMaxValue(screenToNormalized(event.getX())); } if (notifyWhileDragging && listener != null) { listener.rangeSeekBarValuesChanged(getSelectedMinValue(), getSelectedMaxValue()); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: pressedThumb = null; invalidate(); if (listener != null) { listener.rangeSeekBarValuesChanged(getSelectedMinValue(), getSelectedMaxValue()); } break; } return true; }
/** Handles thumb selection and movement. Notifies listener callback on certain events. */ @Override public boolean onTouchEvent(@NonNull MotionEvent event) { if (!isEnabled()) { return false; } int pointerIndex; final int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: // Remember where the motion event started mActivePointerId = event.getPointerId(event.getPointerCount() - 1); pointerIndex = event.findPointerIndex(mActivePointerId); mDownMotionX = event.getX(pointerIndex); final float downMotionY = event.getY(pointerIndex); pressedThumb = evalPressedThumb(mDownMotionX, downMotionY); // Only handle thumb presses. if (pressedThumb == null) { return super.onTouchEvent(event); } setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); updateTouchPosition(pressedThumb.equals(Thumb.MIN)); listener.onTouchStart( touchPositionX, touchPositionY, getSelectedMinValue(), getSelectedMaxValue(), pressedThumb.equals(Thumb.MIN)); break; case MotionEvent.ACTION_MOVE: if (pressedThumb != null) { if (mIsDragging) { trackTouchEvent(event); } else { // Scroll to follow the motion event pointerIndex = event.findPointerIndex(mActivePointerId); final float x = event.getX(pointerIndex); if (Math.abs(x - mDownMotionX) > mScaledTouchSlop) { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); } } if (notifyWhileDragging && listener != null) { updateTouchPosition(pressedThumb.equals(Thumb.MIN)); listener.onRangeSeekBarValuesChanged( this, getSelectedMinValue(), getSelectedMaxValue(), touchPositionX, touchPositionY, pressedThumb.equals(Thumb.MIN)); } } break; case MotionEvent.ACTION_UP: if (mIsDragging) { trackTouchEvent(event); onStopTrackingTouch(); setPressed(false); } else { // Touch up when we never crossed the touch slop threshold // should be interpreted as a tap-seek to that location. onStartTrackingTouch(); trackTouchEvent(event); onStopTrackingTouch(); } pressedThumb = null; invalidate(); if (listener != null) { listener.onTouchLeave(); } break; case MotionEvent.ACTION_POINTER_DOWN: { final int index = event.getPointerCount() - 1; // final int index = ev.getActionIndex(); mDownMotionX = event.getX(index); mActivePointerId = event.getPointerId(index); invalidate(); break; } case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(event); invalidate(); break; case MotionEvent.ACTION_CANCEL: if (mIsDragging) { onStopTrackingTouch(); setPressed(false); } invalidate(); // see above explanation break; } return true; }