Skip to content

Instantly share code, notes, and snippets.

@devrath
Created October 23, 2021 10:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devrath/17a37da2fbd4926936f02356b0741200 to your computer and use it in GitHub Desktop.
Save devrath/17a37da2fbd4926936f02356b0741200 to your computer and use it in GitHub Desktop.
Segmented seek bar for chapters in video
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="@color/screen_background"
android:orientation="vertical"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
app:tint="@android:color/white"
app:srcCompat="@drawable/ic_youtube"
android:layout_marginBottom="30dp"/>
<com.example.code.customSeekBar.modified.YoutubeSegmentedSeekBar
android:id="@+id/indicatorProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foregroundGravity="center"
android:paddingLeft="0dp"
android:paddingRight="0dp"
app:progress="0"
app:barHeight="12"
android:progressBackgroundTint="@color/color_progress_bkg_tint"
android:progressTint="@color/color_thumb_tint"
android:secondaryProgressTint="@color/color_secondary_progress_tint"
android:thumbTint="@color/color_thumb_tint"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="color_thumb_tint">#E91051</color>
<color name="screen_background">#30233E</color>
<color name="color_progress_bkg_tint">#4DFFFFFF</color>
<color name="color_secondary_progress_tint">#99FFFFFF</color>
<color name="red">#FA5858</color>
<color name="green">#74DF00</color>
<color name="blue">#58ACFA</color>
<color name="yellow">#D7DF01</color>
<color name="grey">#6E6E6E</color>
</resources>
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatSeekBar
import androidx.core.content.ContextCompat
import com.example.code.R
enum class SeekbarElementType { PROGRESS_BAR, PROGRESS_INDICATOR, PROGRESS_DIVIDER }
class YoutubeSegmentedSeekBar : AppCompatSeekBar {
companion object {
const val DIVIDER_WIDTH = 5F
const val PROGRESS_LEFT_RIGHT_PADDING = 32F
}
// List of points for creating sections
lateinit var indicatorPositions: List<Float>
/** ************************ Paint Objects ************************ **/
private val paintProgressBar = Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = ContextCompat.getColor(context, R.color.color_progress_bkg_tint)
}
private val paintProgress = Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = ContextCompat.getColor(context, R.color.color_thumb_tint)
}
private val paintIndicator = Paint().apply {
isAntiAlias = true
style = Paint.Style.FILL
color = ContextCompat.getColor(context, R.color.screen_background)
}
/** ************************ Paint Objects ************************ **/
/** ************************ Constructors ************************ **/
constructor(context: Context?) : super(context!!)
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int)
: super(context!!, attrs, defStyle)
/** ************************ Constructors ************************ **/
private var progress = 0F
set(state) {
field = state
invalidate()
}
// Use to get the width of the view
private fun width(): Float {
return measuredWidth.toFloat()
}
@Synchronized
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
performDraw(canvas,SeekbarElementType.PROGRESS_BAR)
//performDraw(canvas,SeekbarElementType.PROGRESS_INDICATOR)
performDraw(canvas,SeekbarElementType.PROGRESS_DIVIDER)
}
/** ************************ Draw progress bar elements ************************ **/
// Draw the progress bar
private fun drawProgressBar(canvas: Canvas) {
//drawCenteredBar(canvas, 0F, width())
drawOnCanvas(
canvas, paintProgressBar,PROGRESS_LEFT_RIGHT_PADDING,
width()-PROGRESS_LEFT_RIGHT_PADDING
)
}
// Draw the progress
private fun drawProgress(canvas: Canvas) {
val barWidth = (progress) * width()
drawOnCanvas(canvas, paintProgress,0F, barWidth)
}
// Draw the indicator
private fun drawProgressDivider(canvas: Canvas) {
indicatorPositions.forEach {
val barPositionCenter = it * width()
val barPositionLeft = barPositionCenter - DIVIDER_WIDTH
val barPositionRight = barPositionCenter + DIVIDER_WIDTH
drawOnCanvas(canvas, paintIndicator, barPositionLeft, barPositionRight)
}
}
/** ************************ Draw progress bar elements ************************ **/
private fun performDraw(canvas: Canvas, type: SeekbarElementType) {
when(type){
SeekbarElementType.PROGRESS_BAR -> drawProgressBar(canvas)
SeekbarElementType.PROGRESS_INDICATOR -> drawProgress(canvas)
SeekbarElementType.PROGRESS_DIVIDER -> drawProgressDivider(canvas)
}
}
/**
* This function is used to draw on the canvas
* * This function is a common function for
* * 1 * Drawing the progress bar
* * 2 * Drawing the Indicator
* * 3 * Drawing the progress for the progress bar
*/
private fun drawOnCanvas(canvas: Canvas, paint:Paint, progressLeft: Float, progressRight: Float) {
//val barTop = (measuredHeight - barHeight) / 2
//val barBottom = (measuredHeight + barHeight) / 2
val progressTop = height / 1.8 - minimumHeight / 2
val progressBottom = progressTop / 1.3 + minimumHeight / 2
val barRect = RectF(progressLeft, progressTop.toFloat(),
progressRight, progressBottom.toFloat())
canvas.drawRoundRect(barRect, 50F, 50F, paint)
}
}
class YoutubeSegmentedSeekBarActivity : AppCompatActivity() {
private lateinit var youtubeSegmentedSeekBar: YoutubeSegmentedSeekBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_youtube_segmented_seek_bar)
youtubeSegmentedSeekBar = findViewById(R.id.indicatorProgressBar)
youtubeSegmentedSeekBar.indicatorPositions = listOf(0.13F, 0.34F, 0.57F, 0.85F, 0.92F)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment