LoranWong/range-seek-bar

Need the ability to set numeric steps for integer type.

GoogleCodeExporter opened this issue · 3 comments

Currently, the default step of integer type RangeSeekBar is 1 and is not 
editable.
It's a practical need to be able to set the steps for integer type.

Original issue reported on code.google.com by fanchen...@gmail.com on 10 Sep 2011 at 6:42

Changed type of issue to "enhancement" since this is not a "defect".

Thanks for the feedback and your interest in this widget. I understand that a 
step size could have some useful applications. From a software design 
perspective (at least from mine) though, this should be implemented in a 
seperate class (e.g. DiscreteRangeSeekBar extending RangeSeekBar), since this 
widget should remain rather generic to be useful for many people.

Implementing support for a step size is trivial on one hand. On the other hand, 
there do arise some usability issues. Currently, the thumb positions represent 
the selected values on a continuous scale, thus the thumbs may follow the touch 
of your finger homogeneously. Introducing a step size requires to "jump" or 
"snap" thumb positions at some point. This implies that either the thumbs don't 
always follow your finger (which is nasty) or that they snap to a different 
position when being released (which is nasty too). It's not exactly trivial to 
implement a working and user friendly behavior for that.

I'am looking forward to your feedback on this. Maybe you can provide a patch?

Original comment by tittel@kom.e-technik.tu-darmstadt.de on 20 Sep 2011 at 1:55

  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect
It could snap/animate to the discrete position when you lift your thumb.

Original comment by davejohn...@gmail.com on 8 Aug 2012 at 6:50

  • Added labels: ****
  • Removed labels: ****
Here is a class that implements snapping. The thumbs snap as you move your 
finger.


public class DiscreteRangeSeekBar<T extends Number> extends RangeSeekBar<T> {

    private double normalizedStepSize;

    @SuppressWarnings("unchecked")
    public DiscreteRangeSeekBar(T absoluteMinValue, T absoluteMaxValue, T stepSize, Context context)
            throws IllegalArgumentException {
        super(absoluteMinValue, absoluteMaxValue, context);

        this.normalizedStepSize = valueToNormalized((T) numberType.toNumber(absoluteMinValue.doubleValue()
                + stepSize.doubleValue()));
    }

    @Override
    protected void trackTouchEvent(MotionEvent event) {
        final int pointerIndex = event.findPointerIndex(mActivePointerId);
        final float x = event.getX(pointerIndex);

        if (Thumb.MIN.equals(pressedThumb)) {
            setNormalizedMinValue(findClosestNormalizedStep(screenToNormalized(x)));
        } else if (Thumb.MAX.equals(pressedThumb)) {
            setNormalizedMaxValue(findClosestNormalizedStep(screenToNormalized(x)));
        }
    }

    /**
     * Return normalized location of the nearest step or max (if closer)
     */
    private double findClosestNormalizedStep(double value) {
        int numbStepsBelow = (int) Math.floor(value / normalizedStepSize);

        double stepBelow = normalizedStepSize * numbStepsBelow;
        double stepAbove = Math.min(normalizedStepSize * (numbStepsBelow + 1), 1.0d);

        double distanceBelow = value - stepBelow;
        double distanceAbove = stepAbove - value;

        if (distanceBelow < distanceAbove)
            return stepBelow;
        return stepAbove;
    }
}

Original comment by robneil...@gmail.com on 9 Oct 2012 at 12:18

  • Added labels: ****
  • Removed labels: ****