playback: make dedicated seekbar view

Make a dedicated seekbar view so that does the layout magic necessary
to have an adequate touch target while not taking up too much space.
Isolating this makes handling the playback layout's view much easier.
This commit is contained in:
OxygenCobalt 2021-10-05 19:30:45 -06:00
parent 4b6610d236
commit 5ebe17d0ad
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 167 additions and 213 deletions

View file

@ -23,7 +23,7 @@ import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import androidx.core.view.iterator
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -43,7 +43,7 @@ import org.oxycblt.auxio.util.logD
* also make material sliders usable maybe.
* @author OxygenCobalt
*/
class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
class PlaybackFragment : Fragment() {
private val playbackModel: PlaybackViewModel by activityViewModels()
private val detailModel: DetailViewModel by activityViewModels()
private val binding by memberBinding(FragmentPlaybackBinding::inflate) {
@ -90,9 +90,9 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
// Make marquee of song title work
binding.playbackSong.isSelected = true
binding.playbackSeekBar.apply {
setOnSeekBarChangeListener(this@PlaybackFragment)
isEnabled = true
binding.playbackSeekBar.onConfirmListener = { pos ->
playbackModel.setPosition(pos)
}
// --- VIEWMODEL SETUP --
@ -102,7 +102,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
logD("Updating song display to ${song.name}.")
binding.song = song
binding.playbackSeekBar.max = song.seconds.toInt()
binding.playbackSeekBar.setDuration(song.seconds)
} else {
logD("No song is being played, leaving.")
@ -124,14 +124,8 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.playbackLoop.setImageResource(resId)
}
playbackModel.isSeeking.observe(viewLifecycleOwner) { isSeeking ->
binding.playbackDurationCurrent.isActivated = isSeeking
}
playbackModel.positionAsProgress.observe(viewLifecycleOwner) { pos ->
if (!playbackModel.isSeeking.value!!) {
binding.playbackSeekBar.progress = pos
}
playbackModel.position.observe(viewLifecycleOwner) { pos ->
binding.playbackSeekBar.setProgress(pos)
}
playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) {
@ -165,25 +159,4 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
// inactive. We just need to set the flag.
queueItem.isEnabled = !(userQueue.isEmpty() && nextQueue.isEmpty())
}
// --- SEEK CALLBACKS ---
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
// Only update the display when seeking, as to have PlaybackService seek
// [causing possible buffering] on every movement is really odd.
playbackModel.updatePositionDisplay(progress)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
playbackModel.setSeekingStatus(true)
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
playbackModel.setSeekingStatus(false)
// Confirm the position when seeking stops.
playbackModel.setPosition(seekBar.progress)
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021 Auxio Project
* PlaybackSeeker.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.playback
import android.content.Context
import android.util.AttributeSet
import android.widget.SeekBar
import androidx.constraintlayout.widget.ConstraintLayout
import org.oxycblt.auxio.databinding.ViewSeekBarBinding
import org.oxycblt.auxio.music.toDuration
import org.oxycblt.auxio.util.inflater
/**
* A custom view that bundles together a seekbar with a current duration and a total duration.
* The sub-views are specifically laid out so that the seekbar has an adequate touch height while
* still not having gobs of whitespace everywhere.
* TODO: Fix the padding on this thing
* @author OxygenCobalt
*/
class PlaybackSeekBar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleRes: Int = -1
) : ConstraintLayout(context, attrs, defStyleRes), SeekBar.OnSeekBarChangeListener {
private val binding = ViewSeekBarBinding.inflate(context.inflater, this, true)
private val isSeeking: Boolean get() = binding.playbackDurationCurrent.isActivated
var onConfirmListener: ((Long) -> Unit)? = null
init {
binding.playbackSeekBar.setOnSeekBarChangeListener(this)
}
fun setProgress(seconds: Long) {
// Don't update the progress while we are seeking, that will make the SeekBar jump around.
if (!isSeeking) {
binding.playbackSeekBar.progress = seconds.toInt()
binding.playbackDurationCurrent.text = seconds.toDuration()
}
}
fun setDuration(seconds: Long) {
binding.playbackSeekBar.max = seconds.toInt()
binding.playbackSongDuration.text = seconds.toDuration()
}
override fun onStartTrackingTouch(seekbar: SeekBar) {
binding.playbackDurationCurrent.isActivated = true
}
override fun onStopTrackingTouch(seekbar: SeekBar) {
binding.playbackDurationCurrent.isActivated = false
onConfirmListener?.invoke(seekbar.progress.toLong())
}
override fun onProgressChanged(seekbar: SeekBar, value: Int, fromUser: Boolean) {
if (fromUser) {
// Don't actually seek yet when the user moves the progress bar, as to make our
// player seek during every movement is both inefficient and weird.
binding.playbackDurationCurrent.text = value.toLong().toDuration()
}
}
}

View file

@ -32,7 +32,6 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Parent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.toDuration
import org.oxycblt.auxio.playback.queue.QueueAdapter
import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.playback.state.PlaybackMode
@ -68,7 +67,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
private val mIsInUserQueue = MutableLiveData(false)
// Other
private val mIsSeeking = MutableLiveData(false)
private var mIntentUri: Uri? = null
/** The current song. */
@ -92,13 +90,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
/** The current repeat mode, see [LoopMode] for more information */
val loopMode: LiveData<LoopMode> get() = mLoopMode
val isSeeking: LiveData<Boolean> get() = mIsSeeking
/** The position as a duration string. */
val formattedPosition = Transformations.map(mPosition) {
it.toDuration()
}
/** The position as SeekBar progress. */
val positionAsProgress = Transformations.map(mPosition) {
if (mSong.value != null) it.toInt() else 0
@ -223,17 +214,8 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
/**
* Update the position and push it to [PlaybackStateManager]
*/
fun setPosition(progress: Int) {
playbackManager.seekTo((progress * 1000).toLong())
}
/**
* Update the position without pushing the change to [PlaybackStateManager].
* This is used during seek events to give the user an idea of where they're seeking to.
* @param progress The SeekBar progress to seek to.
*/
fun updatePositionDisplay(progress: Int) {
mPosition.value = progress.toLong()
fun setPosition(progress: Long) {
playbackManager.seekTo((progress * 1000))
}
// --- QUEUE FUNCTIONS ---
@ -428,15 +410,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
mLoopMode.value = playbackManager.loopMode
}
// --- OTHER FUNCTIONS ---
/**
* Set whether the seeking indicator should be highlighted
*/
fun setSeekingStatus(isSeeking: Boolean) {
mIsSeeking.value = isSeeking
}
// --- OVERRIDES ---
override fun onCleared() {
@ -452,9 +425,7 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
}
override fun onPositionUpdate(position: Long) {
if (!mIsSeeking.value!!) {
mPosition.value = position / 1000
}
mPosition.value = position / 1000
}
override fun onQueueUpdate(queue: List<Song>) {

View file

@ -104,55 +104,31 @@
app:layout_constraintTop_toBottomOf="@+id/playback_artist"
tools:text="Album Name" />
<SeekBar
<org.oxycblt.auxio.playback.PlaybackSeekBar
android:id="@+id/playback_seek_bar"
style="@style/Widget.Auxio.SeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="@dimen/spacing_mid_large"
android:paddingEnd="@dimen/spacing_mid_large"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_album"
tools:progress="70" />
<TextView
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_large"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toBottomOf="@+id/playback_seek_bar"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:text="11:38" />
<TextView
android:id="@+id/playback_song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_large"
android:text="@{song.formattedDuration}"
app:layout_constraintBottom_toBottomOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:text="16:16" />
app:layout_constraintTop_toBottomOf="@+id/playback_album" />
<ImageButton
android:id="@+id/playback_loop"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_small"
android:layout_marginStart="@dimen/spacing_medium"
android:contentDescription="@string/desc_change_loop"
android:onClick="@{() -> playbackModel.incrementLoopStatus()}"
android:src="@drawable/ic_loop"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_prev"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
app:layout_constraintTop_toTopOf="@+id/playback_skip_prev" />
<ImageButton
@ -173,16 +149,13 @@
style="@style/Widget.Auxio.Button.Circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginTop="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:contentDescription="@string/desc_play_pause"
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
android:src="@drawable/sel_playing_state"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_pause" />
@ -204,12 +177,12 @@
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_medium"
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next"
app:tint="@color/sel_accented" />

View file

@ -106,42 +106,17 @@
app:layout_constraintTop_toBottomOf="@+id/playback_artist"
tools:text="Album Name" />
<SeekBar
<org.oxycblt.auxio.playback.PlaybackSeekBar
android:id="@+id/playback_seek_bar"
style="@style/Widget.Auxio.SeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="@dimen/spacing_mid_large"
android:paddingEnd="@dimen/spacing_mid_large"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_album"
tools:progress="70" />
<TextView
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_large"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toBottomOf="@+id/playback_seek_bar"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:text="11:38" />
<TextView
android:id="@+id/playback_song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_large"
android:text="@{song.formattedDuration}"
app:layout_constraintBottom_toBottomOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:text="16:16" />
app:layout_constraintTop_toBottomOf="@+id/playback_album" />
<ImageButton
android:id="@+id/playback_loop"
@ -175,16 +150,13 @@
style="@style/Widget.Auxio.Button.Circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginTop="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:contentDescription="@string/desc_play_pause"
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
android:src="@drawable/sel_playing_state"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_pause" />

View file

@ -83,7 +83,6 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_huge"
android:layout_marginEnd="@dimen/spacing_mid_huge"
android:layout_marginBottom="@dimen/spacing_medium"
android:onClick="@{() -> detailModel.navToItem(playbackModel.song.album)}"
android:text="@{song.album.name}"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
@ -91,40 +90,15 @@
app:layout_constraintStart_toStartOf="parent"
tools:text="Album Name" />
<SeekBar
<org.oxycblt.auxio.playback.PlaybackSeekBar
android:id="@+id/playback_seek_bar"
style="@style/Widget.Auxio.SeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:paddingStart="@dimen/spacing_mid_huge"
android:paddingEnd="@dimen/spacing_mid_huge"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:progress="70" />
<TextView
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid_huge"
android:layout_marginBottom="@dimen/spacing_small"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />
<TextView
android:id="@+id/playback_song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_huge"
android:text="@{song.formattedDuration}"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
tools:text="16:16" />
app:layout_constraintStart_toStartOf="parent" />
<ImageButton
android:id="@+id/playback_loop"
@ -158,16 +132,13 @@
style="@style/Widget.Auxio.Button.Circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginTop="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:layout_marginBottom="@dimen/spacing_large"
android:contentDescription="@string/desc_play_pause"
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
android:src="@drawable/sel_playing_state"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_pause" />
<ImageButton

View file

@ -89,53 +89,27 @@
app:layout_constraintStart_toStartOf="parent"
tools:text="Album Name" />
<SeekBar
<org.oxycblt.auxio.playback.PlaybackSeekBar
android:id="@+id/playback_seek_bar"
style="@style/Widget.Auxio.SeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/spacing_mid_large"
android:paddingEnd="@dimen/spacing_mid_large"
android:layout_marginBottom="@dimen/spacing_medium"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:progress="70" />
<TextView
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="@dimen/spacing_mid_large"
android:text="@{playbackModel.formattedPosition}"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />
<TextView
android:id="@+id/playback_song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_large"
android:layout_marginBottom="8dp"
android:text="@{song.formattedDuration}"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintEnd_toEndOf="parent"
tools:text="16:16" />
app:layout_constraintStart_toStartOf="parent" />
<ImageButton
android:id="@+id/playback_loop"
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_small"
android:layout_marginStart="@dimen/spacing_medium"
android:contentDescription="@string/desc_change_loop"
android:onClick="@{() -> playbackModel.incrementLoopStatus()}"
android:src="@drawable/ic_loop"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_prev"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
app:layout_constraintTop_toTopOf="@+id/playback_skip_prev" />
<ImageButton
@ -156,15 +130,13 @@
style="@style/Widget.Auxio.Button.Circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
android:layout_marginBottom="@dimen/spacing_medium"
android:contentDescription="@string/desc_play_pause"
android:onClick="@{() -> playbackModel.invertPlayingStatus()}"
android:src="@drawable/sel_playing_state"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintStart_toStartOf="@+id/playback_duration_current"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
tools:src="@drawable/ic_play" />
<ImageButton
@ -185,12 +157,12 @@
style="@style/Widget.Auxio.Button.Unbounded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_medium"
android:contentDescription="@string/desc_shuffle"
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:src="@drawable/ic_shuffle"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintEnd_toEndOf="@+id/playback_song_duration"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next"
app:tint="@color/sel_accented" />

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<merge
tools:layout_height="wrap_content"
tools:layout_width="match_parent"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<SeekBar
android:id="@+id/playback_seek_bar"
style="@style/Widget.Auxio.SeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/spacing_small"
android:paddingEnd="@dimen/spacing_small"
android:layout_marginBottom="@dimen/spacing_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_small"
android:layout_marginStart="@dimen/spacing_small"
android:textColor="@color/sel_accented_secondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />
<TextView
android:id="@+id/playback_song_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="16:16" />
</merge>
</layout>

View file

@ -47,7 +47,6 @@
</style>
<style name="ThemeOverlay.SeekbarHalo" parent="">
<!-- TODO: Remove this dumb hack and use a slider -->
<item name="colorControlHighlight">@color/overlay_seekbar_halo</item>
</style>
@ -202,7 +201,6 @@
<item name="android:minHeight">@dimen/size_btn_large</item>
<item name="android:minWidth">@dimen/size_btn_large</item>
<item name="android:background">@drawable/ui_circle_ripple</item>
<item name="android:elevation">@dimen/elevation_normal</item>
<item name="android:contentDescription">@string/desc_play_pause</item>
<item name="android:tint">?attr/colorSurface</item>
<item name="android:scaleType">fitCenter</item>