In this tutorial, we’ll discuss and implement SeekBar in our Android Application using Kotlin.
What is Android SeekBar?
SeekBar is a UI element that is an extension of the ProgressBar.
SeekBar adds a draggable thumb to the ProgressBar. It is commonly used in music apps to provide volume control.
SeekBar is like a scale with an upper and lower limit and every step is a single unit.
SeekBar XML Attributes
Some of the important XML attributes of SeekBar are:
android:minWidth/maxWidth/minHeight/maxHeight
: these attributes are used to set the dimensions of the seekbar view. They don’t change the thickness of the SeekBar.android:max/min
: The upper/lower limit of the SeekBar. The android:min is available from Android SDK 26 and above.android:progress
: The current value of the thumb position.android:progressTint
: Here we pass the color for the progress to the left of the thumb position.android:progressBackgroundTint
: This color is displayed for the SeekBar background, to the right of the thumb.android:thumb
: Here we can pass a custom drawable that will act as the thumb of the seek bar.android:thumbTint
: color of the thumb.android:thumbOffset
: The distance between the thumb and the current progress indp
. A negative value shifts the thumb to the right of the progress. A positive one shifts it to the left.style
: it’s used to set custom/predefined styles on the SeekBar. There is a popular seekbar style – “Discrete” – which breaks the progress into discrete intervals.android:tickMark
: Here we pass a drawable, which acts as breakpoints on the SeekBar. The number of breakpoints/tickMarks is equal to android:max.android:tickMarkTint
: used to set a color on the tickMark drawable.android:splitTrack
: This expects a boolean value. By default on Android Lollipop and above this is true. It splits the Seekbar track into two parts – left and right of the SeekBar. This isn’t always visible in white background activities.
Creating SeekBar in Kotlin
We can implement the SeekBar.OnSeekBarChangeListener
interface to create SeekBar programatically. We have to implement the following three Kotlin functions.
fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean)
fun onStartTrackingTouch(p0: SeekBar?)
fun onStopTrackingTouch(p0: SeekBar?)
SeekBar Examples
Let’s look at the different types of SeekBar by setting the above properties.
1. Simple SeekBar
<SeekBar
android:id="@+id/seekbar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
2. SeekBar with Progress Tint Color
<SeekBar
android:id="@+id/seekbar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:max="50"
android:minWidth="100dp"
android:padding="8dp"
android:progress="10"
android:progressBackgroundTint="@android:color/black"
android:progressTint="@color/colorPrimaryDark" />
3. SeekBar with Thumb Tint Color And Offset
<SeekBar
android:id="@+id/seekbar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:progressBackgroundTint="@android:color/holo_green_light"
android:progressTint="@android:color/black"
android:thumbOffset="-20dp"
android:thumbTint="@color/colorPrimary" />
4. SeekBar with TickMarks
<SeekBar
android:id="@+id/seekbar4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="4"
android:padding="8dp"
android:progress="1"
android:progressTint="@android:color/holo_green_light"
android:thumbTint="@color/colorPrimary"
android:tickMark="@drawable/tickmark"
android:tickMarkTint="@color/colorAccent" />
The tickmark.xml drawable is given below.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="-6dp"
android:left="-3dp"
android:top="-6dp">
<shape android:shape="rectangle">
<solid android:color="@color/colorPrimary" />
<stroke
android:width="2dp"
android:color="#1fc78c" />
</shape>
</item>
</layer-list>
5. SeekBar with Custom Style
Here we set Discrete
style with different intervals (max value).
<SeekBar
android:id="@+id/seekbar5"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
<SeekBar
android:id="@+id/seekbar6"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:padding="8dp" />
6. SeekBar with Split Track
The first one has a Split track enabled by default. The second one does not.
<SeekBar
android:id="@+id/seekbar7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:thumbTint="@color/colorPrimary"
android:tickMark="@android:drawable/checkbox_on_background"
android:tickMarkTint="@android:color/black" />
<SeekBar
android:id="@+id/seekbar8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:splitTrack="false"
android:thumbTint="@color/colorPrimary"
android:tickMark="@android:drawable/checkbox_on_background"
android:tickMarkTint="@android:color/black" />
Android SeekBar Kotlin Project Structure
1. Activity XML Code
The code for the activity_main.xml layout is as follows.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_margin="16dp"
android:id="@+id/linearLayout"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="32sp" />
<SeekBar
android:id="@+id/seekbar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
<SeekBar
android:id="@+id/seekbar2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:max="50"
android:minWidth="100dp"
android:padding="8dp"
android:progress="10"
android:progressBackgroundTint="@android:color/black"
android:progressTint="@color/colorPrimaryDark" />
<SeekBar
android:id="@+id/seekbar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:progressBackgroundTint="@android:color/holo_green_light"
android:progressTint="@android:color/black"
android:thumbOffset="-20dp"
android:thumbTint="@color/colorPrimary" />
<SeekBar
android:id="@+id/seekbar4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="4"
android:padding="8dp"
android:progress="1"
android:progressTint="@android:color/holo_green_light"
android:thumbTint="@color/colorPrimary"
android:tickMark="@drawable/tickmark"
android:tickMarkTint="@color/colorAccent" />
<SeekBar
android:id="@+id/seekbar5"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp" />
<SeekBar
android:id="@+id/seekbar6"
style="@android:style/Widget.Material.SeekBar.Discrete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10"
android:padding="8dp" />
<SeekBar
android:id="@+id/seekbar7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:thumbTint="@color/colorPrimary"
android:tickMark="@android:drawable/checkbox_on_background"
android:tickMarkTint="@android:color/black" />
<SeekBar
android:id="@+id/seekbar8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="50"
android:padding="8dp"
android:progress="10"
android:splitTrack="false"
android:thumbTint="@color/colorPrimary"
android:tickMark="@android:drawable/checkbox_on_background"
android:tickMarkTint="@android:color/black" />
<SeekBar
android:id="@+id/seekbar9"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:splitTrack="false"
android:thumb="@mipmap/ic_launcher" />
</LinearLayout>
We’ve created a custom thumb in the last SeekBar.
custom_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<size
android:width="10dp"
android:height="10dp" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item android:drawable="@mipmap/ic_launcher" />
</layer-list>
2. Activity Kotlin Code
The Kotlin code for the MainActivity.kt class is as follows.
package net.androidly.androidlyseekbar
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.SeekBar
import kotlinx.android.synthetic.main.activity_main.*
import android.graphics.PorterDuff
import android.support.v4.content.ContextCompat
class MainActivity : AppCompatActivity(), SeekBar.OnSeekBarChangeListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val seekbar = SeekBar(this)
val layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams.setMargins(30, 30, 30, 30)
seekbar.layoutParams = layoutParams
seekbar.progressDrawable.setColorFilter(ContextCompat.getColor(this, R.color.switch_thumb_normal_material_dark), PorterDuff.Mode.SRC_ATOP)
seekbar.setBackgroundColor(ContextCompat.getColor(this,android.R.color.darker_gray))
seekbar.setOnSeekBarChangeListener(this)
linearLayout.addView(seekbar)
seekbar1.setOnSeekBarChangeListener(this)
seekbar2.setOnSeekBarChangeListener(this)
seekbar3.setOnSeekBarChangeListener(this)
seekbar4.setOnSeekBarChangeListener(this)
seekbar5.setOnSeekBarChangeListener(this)
seekbar6.setOnSeekBarChangeListener(this)
seekbar7.setOnSeekBarChangeListener(this)
seekbar8.setOnSeekBarChangeListener(this)
seekbar9.setOnSeekBarChangeListener(this)
}
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
textView.text = "$p1"
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
}
}
In the above code, we’ve created a SeekBar in Kotlin and added it to the LinearLayout.
We’ve set the SeekBar change listener on each of them. The p1
represents the current progress value which is the same as seekBar.getProgress()
. We are setting this value in the TextView.
Output: