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

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