Changing step values in seekbar?
Asked Answered
T

8

61

I have a seekbar, while moving it I want to change values from 0 to 200. I have a TextView, where I display those values while moving the seekbar. But I don't want to have every value from that interval(0,1,2,3,4,5...), but to have 10, 20, 30...so on. So when I move the seekbar, I want to display 10,20,30,40....to 200. Can somebody give me a hint or an example how to do this?

Tradespeople answered 7/9, 2011 at 5:19 Comment(1)
see How to set seekbar min and max valueTeenyweeny
M
122

Try below code

SeekBar seekBar = (SeekBar)layout.findViewById(R.id.seekbar);
seekBar.setProgress(0);
seekBar.incrementProgressBy(10);
seekBar.setMax(200);
TextView seekBarValue = (TextView)layout.findViewById(R.id.seekbarvalue);
seekBarValue.setText(tvRadius.getText().toString().trim());

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        progress = progress / 10;
        progress = progress * 10;
        seekBarValue.setText(String.valueOf(progress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});

setProgress(int) is used to set starting value of the seek bar

setMax(int) is used to set maximum value of seek bar

If you want to set boundaries of the seekbar then you can check the progressbar value in the onProgressChanged method. If the progress is less than or greater than the boundary then you can set the progress to the boundary you defined.

Masters answered 7/9, 2011 at 5:33 Comment(14)
Wow, this is just a great example! Anyway, can I set the min value of the seek bar to 10? I can set the max, by saying 'seekBar.setMax(200)', there is no a min value. I have some ideas about how to do this, but get errors every time(Tradespeople
Use seekBar.setProgress(10); for set min value to 10 in seek barMasters
I resolved this issue. You see, when I just set a progress to 10, I still was able to set 0, and I wanted to unable this option(so user can't choose a value less than 10). I did this but putting an 'if' statement in ChangeListener.Tradespeople
Means you want minimum value to 10 ? means user can not select lower than 10 ?Masters
You have to declare the text view and the seek bar as field in the class, otherwise you will have an error in the inner class.Vermifuge
Whats the logic behind doing progress = progress / 10; progress = progress * 10; this in onProgressChanged? if you divide something by a constant and again multiply it by same constant wont' it be the initial value?Tetreault
Here is the logic behind progress = progress / 10; progress = progress * 10; E/onProgressChanged:: progress = 19 E/onProgressChanged:: progress / 10 = 1 E/onProgressChanged:: progress * 10 = 10 E/onProgressChanged:: progress = 10 E/onProgressChanged:: progress / 10 = 1 E/onProgressChanged:: progress * 10 = 10 E/onProgressChanged:: progress = 20 E/onProgressChanged:: progress / 10 = 2 E/onProgressChanged:: progress * 10 = 20 E/onProgressChanged:: progress = 21 E/onProgressChanged:: progress / 10 = 2 E/onProgressChanged:: progress * 10 = 20 E/onProgressChanged:: progress = 20Sumerian
@Sumerian then what is the use of seekBar.incrementProgressBy(10);Bein
@Bein as per doc developer.android.com/reference/android/widget/… this is not step rather "Increase the progress bar's progress by the specified amount" int diffSumerian
@Bein seekBar.incrementProgressBy(10) means when you change the progress of the seekbar then it will directly jump in 10 multiply. ex. 0, 10, 20...Masters
@Masters what is tvRadius here, Where did i get thst value;Mahon
@PranavMS That is another textview from which you will initial set value, you can directly assign the default progress there.Masters
Sjd's "logic behind progress" comment is a bit hard to understand, but it does work!Matronymic
I think the logic behind dividing by 10 and multiplying by 10 is in relation to the fact that we will truncate the last digit on dividing by 10. For example if the current value is 173. Dividing by 10 will gives us 17 (because we are storing it as an integer). Multiplying it by 10 gives you 170. Basically 10 is the step size by which you want to increment or decrement the slider.Indecipherable
S
26

You can use the Slider provided by the Material Components Library using the android:stepSize attribute:

    <com.google.android.material.slider.Slider
        android:valueFrom="0"
        android:valueTo="200"
        android:stepSize="10"
       ..>

enter image description here

Spanner answered 1/6, 2020 at 17:0 Comment(0)
T
19

The easieset way I can think of, is simply defining:

SeekBar yourSeekBar = (SeekBar)findViewById(R.id.yourSeekBarId);
yourSeekbar.setMax(20);

Next, override those methods (the empty methods are also required, even if they are empty):

yourSeekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {          
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                if (progress >= 0 && progress <= sizeSeekBar.getMax()) {                        

                    String progressString = String.valueOf(progress * 10);
                    yourTextView.setText(progressString); // the TextView Reference
                    seekBar.setSecondaryProgress(progress);
                }
            }

        }
    });

The idea is to only define 20 values for the seekbar, but always multiply the value by 10 and display that value. If you do not really need 200 values, then there is no point in using 200 values.

Tamarra answered 24/6, 2012 at 18:6 Comment(2)
+1 for simplicity. I searched for other issue, ended up here, but thought you deserve the +1Moulding
This seems like the better solution for sure. I like how it jumps right to the next number. Progressing while the number is static just seems weird.Rock
I
3

You should use the SeekBar.OnSeekBarChangeListener for tracking the progress change. Call mseek.setMax(200). Do a modulo operation on the current value to decide if the textview should be updated or not.

SeekBar.OnSeekBarChangeListener() {

    void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (progress % 10 == 0) {
            textview.setText(""+progress);
        }
    }
}
Indispose answered 7/9, 2011 at 5:28 Comment(3)
This will likely skip values if the bar is not very wide and/or your finger moves fast.Sling
Agree. This was the first thing that came to my mind. and rightly not the right answer.Indispose
This is a nice example, but @Kris Van Bael is right, - it skips values.Tradespeople
I
3

You can also achieve this by defining custom SeekBar class as below

public class CustomSeekBar extends AppCompatSeekBar {


int SEEKBAR_MULTIPLIER = 1;

public CustomSeekBar(Context context) {
    super(context);
}

public CustomSeekBar(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public void setSeekBarConfig( int SEEKBAR_MULTIPLIER, int SEEKBAR_MAX){
    setMax(SEEKBAR_MAX);
    this.SEEKBAR_MULTIPLIER = SEEKBAR_MULTIPLIER;
}

@Override
public int getProgress() {
    return super.getProgress() * SEEKBAR_MULTIPLIER;
}
}

And can use by following manner

 CustomSeekBar mCustomSeekBar = (CustomSeekBar) findViewById(R.id.customSeekBar);
 mSeekBar.setSeekBarConfig(10,20);

In xml you should add CustomSeekBar instead of SeekBar

<*.CustomSeekBar
    com.quemb.qmbform.view:setSeekBarConfig="10"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/seekBar" />

So that you can reuse the custom seekBar in entire App with out repeating whole extra calculation.

Inherited answered 9/9, 2017 at 6:56 Comment(0)
C
0

for the minimum issue, you can set an offset on your progress. This way, the user can't go under your minimal value.

int offset = 10;

seekBar seekBar = (SeekBar)layout.findViewById(R.id.seekbar);
seekBar.setProgress(0);
seekBar.setMax(190); //with the offset, you need to adapt the max value
TextView seekBarValue = (TextView)layout.findViewById(R.id.seekbarvalue);
seekBarValue.setText(""+(seekBar.getProgress() + offset));

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        progress += offset;

        seekBarValue.setText(String.valueOf(progress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});
Crouse answered 14/1, 2016 at 11:40 Comment(0)
B
0

use Math.round function

fun round(n: Int): Int {
    // Smaller multiple
    val a = n / 10 * 10
    // Larger multiple
    val b = a + 10
    // Return of closest of two
    return if (n - a > b - n) b else a
}
Byre answered 10/7, 2018 at 11:43 Comment(0)
C
0

One possible solution would be to set seekBar.setMax(20) (or android:max="20" in XML), and whenever you use or display the value, multiply it by 10.

The SeekBar would then appear to move at least 20 at a time.

Caitlin answered 1/7, 2019 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.