Android SeekBar Kotlin Example

Android SeekBar is a user-controlled progress widget. It looks similar to a progress bar, but it adds a draggable thumb so the user can choose a numeric value by moving the thumb left or right.

In this Kotlin Android SeekBar tutorial, you will learn how to add a SeekBar in an XML layout, listen for progress changes, get the selected value, detect when the user starts and stops dragging, and use a modern AndroidX View Binding version for new projects.

A SeekBar is commonly used for volume, brightness, media playback position, font size, timer duration, percentage selection, and similar settings where the user can choose a value within a range.

The following GIF shows how a user can touch the trackbar, and seek it to the left or right of the bar.

Android SeekBar - Kotlin Example

Android SeekBar progress value and listener callbacks in Kotlin

A SeekBar stores its selected position as an integer progress value. By default, the progress range is from 0 to 100. You can change the upper limit with android:max in XML or with max in Kotlin. The selected value can be read from seekBar.progress.

SeekBar partPurpose in Kotlin Android
android:maxSets the maximum progress value for the SeekBar.
android:progressSets the initial selected progress value.
setOnSeekBarChangeListener()Registers callbacks for progress changes and drag events.
onProgressChanged()Runs when the progress value changes.
fromUserTells whether the progress change came from the user or from code.

Kotlin Android SeekBar XML and OnSeekBarChangeListener code

Following is a quick code snippet to use SeekBar in your layout file and Kotlin file respectively.

</>
Copy
<SeekBar
    android:id="@+id/seekbar"
    android:layout_width="match_parent"
    android:padding="15dp"
    android:layout_height="wrap_content" />
</>
Copy
import android.os.Bundle
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : /** Other Classes, */OnSeekBarChangeListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        this.seekbar!!.setOnSeekBarChangeListener(this)
    }

    override fun onProgressChanged(seekBar: SeekBar, progress: Int,
                                   fromUser: Boolean) {
		// called when progress is changed
    }

    override fun onStartTrackingTouch(seekBar: SeekBar) {
        // called when tracking the seekbar is started
    }

    override fun onStopTrackingTouch(seekBar: SeekBar) {
        // called when tracking the seekbar is stopped
    }
}

By default, the range of progress is [0,100] in steps of 1.

The older snippet above uses Kotlin synthetic view access. It is kept here for readers maintaining old projects. For new Android projects, prefer View Binding, shown later in this tutorial.

Add a SeekBar to an Android layout and handle progress changes

Following is a step by step guide of what is happening in the above code snippet to use SeekBar.

Step 1: Create a SeekBar in layout file.

</>
Copy
<SeekBar
    android:id="@+id/seekbarView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Step 2: Add OnSeekBarChangeListener to the interface list of your Activity.

</>
Copy
class MainActivity : /** Other Classes, */OnSeekBarChangeListener {

}

Step 3: Set setOnSeekBarChangeListener to the SeekBar.

</>
Copy
seekbarView!!.setOnSeekBarChangeListener(this)

Step 4: We have to override the following three methods of OnSeekBarChangeListener.

</>
Copy
override fun onProgressChanged(seekBar: SeekBar, progress: Int,
                               fromUser: Boolean) {
	// called when progress is changed
}

override fun onStartTrackingTouch(seekBar: SeekBar) {
    // called when tracking the seekbar is started
}

override fun onStopTrackingTouch(seekBar: SeekBar) {
    // called when tracking the seekbar is stopped
}

Get the selected SeekBar value in Kotlin

You can get the current SeekBar value from the progress property. Inside onProgressChanged(), Android also gives the new value through the progress parameter.

</>
Copy
val currentValue = seekbarView?.progress ?: 0

Use the fromUser parameter when you need to react only to user dragging and ignore progress changes made by your Kotlin code.

</>
Copy
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
    if (fromUser) {
        progressView?.text = progress.toString()
    }
}

Set maximum progress and initial value for Android SeekBar

For a simple range that starts from 0, set android:max and android:progress in the layout. In the following XML, the SeekBar starts at 25 and can move up to 100.

</>
Copy
<SeekBar
    android:id="@+id/volumeSeekBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="25" />

When you want the visible value to start from a number other than 0, a reliable approach is to map the SeekBar progress to your required value in Kotlin.

</>
Copy
val minValue = 10
val maxValue = 60

binding.volumeSeekBar.max = maxValue - minValue
binding.volumeSeekBar.progress = 0

binding.volumeSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
        val actualValue = minValue + progress
        binding.progressValue.text = actualValue.toString()
    }

    override fun onStartTrackingTouch(seekBar: SeekBar) = Unit

    override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
})

Complete Kotlin Android SeekBar example with progress text

Following are the details of the Android Application we created for this example.

Application NameSeekBarExample
Company nametutorialkart.com
Minimum SDKAPI 21: Android 5.0 (Lollipop)
ActivityEmpty Activity

You may keep rest of the values as default and create Android Application with Kotlin Support.

The following project files show a working SeekBar example. The TextView named progress displays the current progress value, and the TextView named seekbarStatus displays the drag state.

activity_main.xml

</>
Copy
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tutorialkart.seekbarexample.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="- -"
            android:padding="20dp"/>
        <TextView
            android:id="@+id/seekbarStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="- -"
            android:padding="20dp"/>

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

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

MainActivity.kt

</>
Copy
package com.tutorialkart.seekbarexample

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(),OnSeekBarChangeListener {

    private var progressView: TextView? = null
    private var seekbarStatusView: TextView? = null
    private var seekbarView: SeekBar? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        progressView = this.progress
        seekbarStatusView = this.seekbarStatus
        seekbarView = this.seekbar
        seekbarView!!.setOnSeekBarChangeListener(this)
    }

    override fun onProgressChanged(seekBar: SeekBar, progress: Int,
                                   fromUser: Boolean) {
        progressView!!.text = progress.toString()
        seekbarStatusView!!.text = "Tracking Touch"
    }

    override fun onStartTrackingTouch(seekBar: SeekBar) {
        seekbarStatusView!!.text = "Started Tracking Touch"
    }

    override fun onStopTrackingTouch(seekBar: SeekBar) {
        seekbarStatusView!!.text = "Stopped Tracking Touch"
    }
}

Output

Android SeekBar - Kotlin Example

Modern AndroidX SeekBar Kotlin example with View Binding

New Android projects usually use AndroidX and View Binding instead of Kotlin synthetic imports. The following version shows the same SeekBar behavior with a generated binding class.

Enable View Binding in build.gradle.kts

</>
Copy
android {
    buildFeatures {
        viewBinding = true
    }
}

activity_main.xml for AndroidX

</>
Copy
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="24dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/progressValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="12dp"
            android:text="25" />

        <TextView
            android:id="@+id/seekbarStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="12dp"
            android:text="Move the SeekBar" />

        <SeekBar
            android:id="@+id/volumeSeekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100"
            android:progress="25" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt with View Binding

</>
Copy
package com.tutorialkart.seekbarexample

import android.os.Bundle
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import com.tutorialkart.seekbarexample.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.progressValue.text = binding.volumeSeekBar.progress.toString()

        binding.volumeSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                binding.progressValue.text = progress.toString()

                if (fromUser) {
                    binding.seekbarStatus.text = "Changed by user"
                } else {
                    binding.seekbarStatus.text = "Changed by code"
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar) {
                binding.seekbarStatus.text = "Started dragging"
            }

            override fun onStopTrackingTouch(seekBar: SeekBar) {
                binding.seekbarStatus.text = "Stopped dragging"
            }
        })
    }
}

Difference between SeekBar and ProgressBar in Android

A ProgressBar and a SeekBar both represent progress, but they are used for different interaction patterns.

WidgetHow it is usedTypical example
ProgressBarShows progress to the user. The user usually does not control it.File upload progress, loading progress, download progress.
SeekBarLets the user change a progress value by dragging the thumb.Volume control, brightness setting, media seek position.

Common Android SeekBar Kotlin mistakes and fixes

  • Using Kotlin synthetics in a new project: Use View Binding or findViewById() instead of kotlinx.android.synthetic in new Android projects.
  • Ignoring fromUser: Check fromUser if your app must respond only when the user changes the SeekBar manually.
  • Reading the value before the layout is set: Call setContentView() or inflate View Binding before accessing the SeekBar.
  • Expecting a non-zero minimum without mapping: If your value range is 10 to 60, set SeekBar progress from 0 to 50 and add 10 in Kotlin.
  • Using !! everywhere: Prefer View Binding or safe calls to avoid unnecessary null pointer errors.

Android SeekBar Kotlin FAQ

What is SeekBar in Android Kotlin?

SeekBar is an Android widget that lets the user select an integer value from a range by dragging a thumb along a track. In Kotlin, you usually handle it with SeekBar.OnSeekBarChangeListener.

How to get value from SeekBar in Kotlin?

Use the progress property. For example, val value = binding.volumeSeekBar.progress gets the current selected value from the SeekBar.

What is the difference between ProgressBar and SeekBar?

ProgressBar is mainly for displaying progress, while SeekBar is for user input. A SeekBar has a draggable thumb so the user can change the value.

How do I set the range of an Android SeekBar?

Set the maximum value using android:max in XML or seekBar.max in Kotlin. For a range that does not start at 0, map the progress value in Kotlin, such as actualValue = minValue + progress.

Should I use Kotlin synthetic imports for SeekBar examples?

Use Kotlin synthetic imports only when maintaining an older project that already uses them. For new Android projects, View Binding is the safer and current approach.

Editorial QA checklist for this Android SeekBar Kotlin tutorial

  • The XML layout includes a valid SeekBar id, width, height, and optional android:max or android:progress.
  • The Kotlin code reads the selected value from progress or the onProgressChanged() callback parameter.
  • The tutorial explains onStartTrackingTouch(), onStopTrackingTouch(), and fromUser with SeekBar-specific context.
  • The legacy synthetic example is clearly separated from the modern View Binding example.
  • The output image remains the existing Android SeekBar Kotlin example GIF.

Android SeekBar Kotlin references

Android SeekBar Kotlin example summary

In this Android TutorialAndroid SeekBar – Kotlin Example, we have learnt how to add a SeekBar to an Android layout, read its progress value in Kotlin, respond to drag callbacks, set a range, and use a modern View Binding approach for new Android projects.