59

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?

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
lomza
  • 9,412
  • 15
  • 70
  • 85
  • see [How to set seekbar min and max value](https://stackoverflow.com/a/52350712/2722270) – Weiyi Sep 16 '18 at 12:11

8 Answers8

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.

Dharmendra
  • 33,296
  • 22
  • 86
  • 129
  • 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( – lomza Sep 07 '11 at 09:39
  • Use seekBar.setProgress(10); for set min value to 10 in seek bar – Dharmendra Sep 07 '11 at 09:47
  • 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. – lomza Sep 07 '11 at 10:16
  • Means you want minimum value to 10 ? means user can not select lower than 10 ? – Dharmendra Sep 07 '11 at 10:26
  • 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. – Tony_craft Mar 24 '14 at 11:10
  • 6
    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? – Prajeet Shrestha Jan 29 '15 at 04:19
  • 1
    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 = 20 – Sjd Oct 07 '16 at 07:59
  • @Sjd then what is the use of seekBar.incrementProgressBy(10); – OnePunchMan Oct 18 '16 at 07:49
  • @OnePunchMan as per doc https://developer.android.com/reference/android/widget/ProgressBar.html#incrementProgressBy(int) this is not step rather "Increase the progress bar's progress by the specified amount" int diff – Sjd Oct 18 '16 at 13:36
  • @OnePunchMan seekBar.incrementProgressBy(10) means when you change the progress of the seekbar then it will directly jump in 10 multiply. ex. 0, 10, 20... – Dharmendra Nov 04 '16 at 12:52
  • @Dharmendra what is `tvRadius` here, Where did i get thst value; – Pranav MS Jan 17 '17 at 06:32
  • @PranavMS That is another textview from which you will initial set value, you can directly assign the default progress there. – Dharmendra Jan 18 '17 at 11:53
  • Sjd's "logic behind progress" comment is a bit hard to understand, but it _does_ work! – langsmith Jun 27 '19 at 00:56
  • 1
    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. – Dhruv Sangvikar Aug 09 '20 at 21:25
24

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

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
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.

Shahar
  • 2,269
  • 1
  • 27
  • 34
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);
        }
    }
}
Ron
  • 24,175
  • 8
  • 56
  • 97
2

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.

Ebin Joy
  • 2,690
  • 5
  • 26
  • 39
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) {

    }
});
T.Durand
  • 77
  • 2
  • 11
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
}
shashank s
  • 151
  • 1
  • 5
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.

Adam Howell
  • 415
  • 1
  • 11
  • 24