I'm trying to make specific color line on the seekbar slider, like trying to tell the user that there's specific event on that timestamp of the video.
I want that extra color line is top of the slider line, and the line is bottom of the scrubber.
My expectation is like this:
The result i got:
My code is like this:
Player:
val seekBar = findViewById<EventOverlayBar>(R.id.seek_bar)
val eventSections = listOf(
Pair(10, 20), // Event 1 from 10s to 20s
Pair(40, 50) // Event 2 from 40s to 50s
)
val duration = 100 // The video is 100 seconds duration for the example
seekBar.setEventSections(eventSections, duration)
Constructor:
class EventOverlayBar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : androidx.appcompat.widget.AppCompatSeekBar(context, attrs) {
private val eventPaint = Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
private var eventSections: List<Pair<Int, Int>> = listOf()
private var duration: Int = 0
fun setEventSections(adSections: List<Pair<Int, Int>>, duration: Int) {
this.eventSections = adSections
this.duration = duration
invalidate()
}
override fun dispatchDraw(canvas: Canvas) {
super.dispatchDraw(canvas)
drawEventSections(canvas)
}
private fun drawEventSections(canvas: Canvas) {
if (duration == 0) return
val barWidth = width - paddingLeft - paddingRight
val barHeight = height / 2
for ((start, end) in eventSections) {
val startX = paddingLeft + (start.toFloat() / duration) * barWidth
val endX = paddingLeft + (end.toFloat() / duration) * barWidth
canvas.drawRect(startX, barHeight.toFloat(), endX, (barHeight + 10).toFloat(), eventPaint)
}
}
}
Seekbar:
<com.example.EventOverlayBar
android:id="@+id/exo_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
I think i found a way to do this, it doesn't meet my earlier expectation but I'll take it instead.
There's a thing named ad marker on DefaultTimeBar, but it can't use custom width for each multiple groups. So instead of hard coded the width, I'm using start and end of the event instead.
Here is my latest code:
<androidx.media3.ui.DefaultTimeBar
android:id="@+id/exo_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Player:
val adGroupTimesMs = longArrayOf(1000, 5000)
val adGroupPlayed = adGroupTimesMs.map { false }.toBooleanArray()
seekBar.apply {
setAdMarkerColor(resources.getColor(android.R.color.holo_red_dark))
setPlayedAdMarkerColor(resources.getColor(android.R.color.holo_red_dark))
setAdGroupTimesMs(adGroupTimesMs, adGroupPlayed, adGroupTimesMs.size)
}