How to Create Vertical SeekBar in Android Without External Library(Kotin+AndroidX)

Hitesh Sahu
3 min readAug 7, 2020

Many times we want to show a vertical progress bar for example when you are creating a Audio Equalizer or you want to show Volume Bars like One Plus 8

Add this class in your project:

  • First trick it does is it rotates the canvas of Android SeekBar anticlockwise -90 degrees.
  • Second trick it does is it set progress based on touch position.

Progress = MaxProgress-(TouchY/Height)*MaxProgress

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.content.ContextCompat

/**
* Vertical Progress Bar For Android Apps
*/
class VerticalSeekBar : AppCompatSeekBar {

constructor(context: Context) : super(context) {
initView(context)
}
constructor(
context: Context,
attrs: AttributeSet?,
defStyle: Int) : super(context, attrs, defStyle) {
initView(context)
}
constructor(
context: Context,
attrs: AttributeSet?) : super(context, attrs) {
initView(context)
}

private fun initView(context: Context) {
// Set Custom Progress Bar Drawable
progressDrawable
= ContextCompat.getDrawable(context, R.drawable.vertical_progress_selector)
// Set Custom Thumb
thumb
= ContextCompat.getDrawable(context, R.drawable.vertical_progress_thumb)
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int{
super.onSizeChanged(h, w, oldh, oldw)
}

@Synchronized
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec)
setMeasuredDimension(measuredHeight, measuredWidth)
}

override fun onDraw(c: Canvas) {
c.rotate(-90f)
c.translate(-height.toFloat(), 0f)
super.onDraw(c)
}

@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
if (!isEnabled) {
return false
}
when (event.action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> {
progress = max - (max * event.y / height).toInt()
onSizeChanged(width, height, 0, 0)
}
MotionEvent.ACTION_CANCEL -> {
}
}
return true
}
}

Create Custom Thumb & Progress for SeekBar

Add this vertical_progress_thumb.xml in drawable-nodpi
This will draw a white(#ffffff) rectangle which we will use as Thumb for SeekBar. You can customize it as you like.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<size
android:width="50dp"
android:height="52dp"
/>
</shape>
</item>
</layer-list>

Next add vertical_progress_selector.xml in drawable-nodpi

This drawable define how the background and Progress of Seek Bar should look like.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@android:id/background"
android:drawable="@drawable/background_fill"
/>
<item android:id="@android:id/progress">
<clip android:drawable="@drawable/progress_fill" />
</item>

</layer-list>

Add background_fill.xml. This drawable define for SeekBar background. Here it is another simple Rectangle but with grey color(#888888)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="6dp"
android:left="-6dp"
android:right="-6dp"
android:top="6dp"
>

<shape android:shape="rectangle">
<solid android:color="#888888" />
<stroke
android:width="5dp"
android:color="@android:color/transparent"
/>
</shape>
</item>
</layer-list>

progress_fill.xml defines how progress will look like. This is another Rectangle but with Linear Gradient Filled.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="6dp"
android:left="-6dp"
android:right="-6dp"
android:top="6dp"
>

<shape android:shape="rectangle">
<solid android:color="@color/white" />
<stroke
android:width="1dp"
android:color="@android:color/transparent"
/>

<gradient
android:angle="90"
android:endColor="#ffffff"
android:startColor="#aeaeae"
android:type="linear"
/>
</shape>
</item>
</layer-list>

Usage

After this simply add Verical Seekbar just like any normal SeekBar this

<com.example.demo.VerticalSeekBar
android:id="@+id/audioSeekBar"
android:layout_width="120dp"
android:layout_gravity="center"
android:layout_height="698dp"
android:progress="30"
android:max="100"
/>

Now you can modify it as you see it fits. Please hit the clap button. That help me keep motivated to share my knowledge and write new Story

With that my friend. Hopefully, I have covered everything that is needed for you to create a vertical seek bar. Feel free to drop in comments if you still have some questions, I will be happy to help.

Also, if you find any grammatical mistakes in the post, please point it out so I can improvise. It will be highly appreciated. You can see my work in my web links:

Lab: https://hiteshsahu.com/
Tweeter: https://twitter.com/HiteshSahu_
GitHub: https://github.com/hiteshsahu

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Responses (2)

Write a response