9


I want to use a SeekBar in my android app. My minsdk version is must be 23. The compiler said setMin of SeekBar needs at least API level 26. Do I need some special support library for a simple SeekBar setMin?

I use Android Studio 3.0.1 on Linux. My build.gradle is like this:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.zamek.boyler"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    ...


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

my layout snippet:

<SeekBar
        android:id="@+id/sb_hysteresis"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="15dp"/>

my Activity code snippets:

import android.widget.SeekBar;
...
 private SeekBar hysteresis;
...
this.hysteresis = findViewById(R.id.sb_hysteresis);
this.hysteresis.setMin(10); <--Compiler said:Call requires API level 26 (current min is 23): android.widget.AbsSeekBar#setMin

thx,
Zamek

Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33
zamek 42
  • 793
  • 1
  • 9
  • 15
  • Yes it seems you need to be >= api 26 for using/setting the property. More of it on this [link](https://stackoverflow.com/questions/3033135/android-seekbar-minimum-value) – udit7395 Jan 27 '18 at 19:56
  • 1
    Thx, I found a simple FLoatSeekBar in here: https://gist.github.com/niusounds/9505361 It works well. – zamek 42 Jan 28 '18 at 07:41

4 Answers4

15

SeekBar setMin() method was added in API level 26.

If you want to limit your SeekBar minimum value then you have to implement it manually.

 seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int min = 5;
                if(progress < min) {
                    seekBar.setProgress(min);
                }

            }
Zeeshan
  • 11,851
  • 21
  • 73
  • 98
  • I would suggest to call `return` after `setProgress` so that it won't execute whatever below, and after setting new progress, this `onProgressChanged` will be called one more time with the expected value (which is `min`) –  Jan 02 '21 at 06:34
13

I agree with Zeeshan's response but my approach to it is a bit different, maybe it'll help someone trying to achieve this.

First define your min and max values.

private static int MAX_VALUE = 220;
private static int MIN_VALUE = 50;

Then setup the seekbar max like this. By doing so you will make your seekbar have only the amount of values of the interval you wish to define.

seekbar.setMax(MAX_VALUE - MIN_VALUE);

After that whenever you check for the seekbar's value you must first add the min value that we defined.

@Override
public void onProgressChanged(SeekBar seekBar, int value, boolean fromUser) {
    displayValue((value + MIN_VALUE) + "cm");
}
TheNewKid
  • 201
  • 4
  • 7
0

For those having crashes on API level < 26 because the method setMin() supposedly doesn't exist, do remember that setting it as an argument in your XML file as android:min=... invokes this method.

Might save you a few hours (days, really) of replicating/hair pulling.

Alec Gerona
  • 2,806
  • 1
  • 24
  • 24
0

I created some extension method to be able to handle the setMin

private data class SeekBarMin(
    val min: Int
)

fun SeekBar.setMinMax(
    min: Int, max: Int
) {
    tag = SeekBarMin(min)
    this.max = (max - min)
}

var SeekBar.realProgress: Int
    get() = progress + ((tag as? SeekBarMin)?.min ?: 0)
    set(value) {
        this.progress = value - ((tag as? SeekBarMin)?.min ?: 0)
    }

inline fun SeekBar.setOnProgressChanged(
    crossinline action: (seekbar: SeekBar?, progress: Int, fromUser: Boolean) -> Unit
) {
    setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
        override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
            action(p0, realProgress, p2)
        }

        override fun onStartTrackingTouch(p0: SeekBar?) {
            // No needed
        }

        override fun onStopTrackingTouch(p0: SeekBar?) {
            // No needed
        }
    })
}

In your View, the usage is simple :

seekbar.setMinMax(10, 50)
seekbar.realProgress = 30

seekbar.setOnProgressChanged { v, progress, fromUser ->
    
}
Luoman
  • 1
  • 1