playback: add split ui in landscape

Add a split playback UI in landscape mode.

Apparently the mere act of doing this also fixes the infurating
window inset issue I previously did either. Odd.
This commit is contained in:
OxygenCobalt 2022-08-03 16:00:18 -06:00
parent 772fe7df3b
commit 7543f1defc
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 178 additions and 399 deletions

View file

@ -28,8 +28,9 @@ at the cost of longer loading times
- Fixed default material theme being used before app shows up
- Fixed shuffle shortcut and file opening not working on startup on some devices
- Fixed issue where the notification position would not match if one seeked when paused
- Fixed issue where widget covers would not load
- Fixed issue where widget could not be sized to it's smallest form
- Fixed issue where restored state would override a song if it was played early enough
in startup
#### What's Changed
- Play and skip icons are filled again

View file

@ -23,10 +23,12 @@ import android.view.ViewTreeObserver
import android.view.WindowInsets
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isInvisible
import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialFadeThrough
import kotlin.math.max
import kotlin.math.min
@ -75,14 +77,29 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
binding.handleWrapper.setOnClickListener {
if (queueSheetBehavior != null) {
unlikelyToBeNull(binding.handleWrapper).setOnClickListener {
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED &&
queueSheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
queueSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
} else {
binding.queueSheet.apply {
background =
MaterialShapeDrawable.createWithElevationOverlay(context).apply {
fillColor = context.getAttrColorSafe(R.attr.colorSurface).stateList
elevation = context.getDimenSafe(R.dimen.elevation_normal)
}
setOnApplyWindowInsetsListener { v, insets ->
v.updatePadding(top = insets.systemBarInsetsCompat.top)
insets
}
}
}
// --- VIEWMODEL SETUP ---
@ -121,16 +138,11 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
val playbackRatio = max(playbackSheetBehavior.calculateSlideOffset(), 0f)
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
val outPlaybackRatio = 1 - playbackRatio
val halfOutRatio = min(playbackRatio * 2, 1f)
val halfInPlaybackRatio = max(playbackRatio - 0.5f, 0f) * 2
val halfOutQueueRatio = min(queueRatio * 2, 1f)
val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2
binding.exploreNavHost.apply {
alpha = outPlaybackRatio
@ -141,6 +153,13 @@ class MainFragment :
requireContext().getDimenSafe(R.dimen.elevation_normal) * outPlaybackRatio
playbackSheetBehavior.sheetBackgroundDrawable.alpha = (outPlaybackRatio * 255).toInt()
val queueSheetBehavior = binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
if (queueSheetBehavior != null) {
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
val halfOutQueueRatio = min(queueRatio * 2, 1f)
val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2
binding.playbackBarFragment.apply {
alpha = max(1 - halfOutRatio, halfInQueueRatio)
isInvisible = alpha == 0f
@ -166,6 +185,30 @@ class MainFragment :
// hide it, make sure we keep it hidden.
tryHideAll()
}
} else {
binding.playbackBarFragment.apply {
alpha = 1 - halfOutRatio
isInvisible = alpha == 0f
lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio }
}
binding.playbackPanelFragment.apply {
alpha = halfInPlaybackRatio
isInvisible = alpha == 0f
}
binding.queueSheet.apply {
alpha = halfInPlaybackRatio
isInvisible = alpha == 0f
}
if (playbackModel.song.value == null) {
// Sometimes lingering drags can un-hide the playback sheet even when we intend to
// hide it, make sure we keep it hidden.
tryHideAll()
}
}
return true
}
@ -221,10 +264,10 @@ class MainFragment :
if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN &&
playbackSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
queueSheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
}
}
@ -234,13 +277,13 @@ class MainFragment :
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackSheetBehavior
if (playbackSheetBehavior.state == BottomSheetBehavior.STATE_HIDDEN) {
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
playbackSheetBehavior.isDraggable = true
playbackSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
queueSheetBehavior.isDraggable = true
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
queueSheetBehavior?.isDraggable = true
}
}
@ -251,13 +294,17 @@ class MainFragment :
if (playbackSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) {
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
playbackSheetBehavior.isDraggable = false
queueSheetBehavior.isDraggable = false
queueSheetBehavior?.apply {
isDraggable = false
state = BottomSheetBehavior.STATE_COLLAPSED
}
playbackSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
playbackSheetBehavior.apply {
isDraggable = false
state = BottomSheetBehavior.STATE_HIDDEN
}
}
}
@ -272,9 +319,10 @@ class MainFragment :
val binding = requireBinding()
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior
binding.queueSheet.coordinatorLayoutBehavior as QueueSheetBehavior?
if (queueSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
if (queueSheetBehavior != null &&
queueSheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED) {
queueSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
return
}

View file

@ -36,7 +36,6 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis
import java.lang.reflect.Field
import kotlin.math.abs
@ -78,6 +77,14 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
binding.homeToolbar.menu.findItem(R.id.submenu_sorting)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
}
override fun onCreateBinding(inflater: LayoutInflater) = FragmentHomeBinding.inflate(inflater)
override fun onBindingCreated(binding: FragmentHomeBinding, savedInstanceState: Bundle?) {
@ -146,11 +153,6 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
when (item.itemId) {
R.id.action_search -> {
logD("Navigating to search")
// Search has no contextual relation to home, use fade transitions
enterTransition = MaterialFadeThrough()
returnTransition = MaterialFadeThrough()
exitTransition = MaterialFadeThrough()
reenterTransition = MaterialFadeThrough()
findNavController().navigate(HomeFragmentDirections.actionShowSearch())
}
R.id.action_settings -> {
@ -358,11 +360,6 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
else -> return
}
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
findNavController().navigate(action)
}

View file

@ -154,7 +154,7 @@ val RecyclerView.canScroll: Boolean
get() = computeVerticalScrollRange() > height
val View.coordinatorLayoutBehavior: CoordinatorLayout.Behavior<*>?
get() = (layoutParams as CoordinatorLayout.LayoutParams).behavior
get() = (layoutParams as? CoordinatorLayout.LayoutParams)?.behavior
/** Converts this color to a single-color [ColorStateList]. */
val @receiver:ColorRes Int.stateList

View file

@ -1,171 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback"
app:navigationIcon="@drawable/ic_down_24"
app:title="@string/lbl_playback"
tools:subtitle="@string/lbl_all_songs" />
<org.oxycblt.auxio.image.StyledImageView
android:id="@+id/playback_cover"
style="@style/Widget.Auxio.Image.Full"
android:layout_margin="@dimen/spacing_large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/playback_song_container"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:staticIcon="@drawable/ic_song_48" />
<!-- TextView is wrapped in a container so that marquee doesn't break -->
<FrameLayout
android:id="@+id/playback_song_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_large"
app:layout_constraintBottom_toTopOf="@+id/playback_artist"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
app:layout_constraintVertical_chainStyle="packed">
<TextView
android:id="@+id/playback_song"
style="@style/Widget.Auxio.TextView.Primary"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:text="Song Name" />
</FrameLayout>
<TextView
android:id="@+id/playback_artist"
style="@style/Widget.Auxio.TextView.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="@+id/playback_song_container"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/playback_song_container"
app:layout_constraintTop_toBottomOf="@+id/playback_song_container"
tools:text="Artist Name" />
<TextView
android:id="@+id/playback_album"
style="@style/Widget.Auxio.TextView.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="@+id/playback_song_container"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/playback_song_container"
app:layout_constraintTop_toBottomOf="@+id/playback_artist"
tools:text="Album Name" />
<org.oxycblt.auxio.playback.StyledSeekBar
android:id="@+id/playback_seek_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
app:layout_constraintBottom_toTopOf="@+id/playback_controls_container"
app:layout_constraintEnd_toEndOf="@+id/playback_album"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="@+id/playback_album"
app:layout_constraintTop_toBottomOf="@+id/playback_album" />
<org.oxycblt.auxio.playback.ForcedLTRFrameLayout
android:id="@+id/playback_controls_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_repeat"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_huge"
android:contentDescription="@string/desc_change_repeat"
app:icon="@drawable/ic_repeat_off_24"
app:iconTint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_prev"
app:layout_constraintEnd_toStartOf="@+id/playback_skip_prev"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toTopOf="@+id/playback_skip_prev" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_huge"
android:contentDescription="@string/desc_skip_prev"
app:icon="@drawable/ic_skip_prev_24"
app:layout_constraintBottom_toBottomOf="@+id/playback_play_pause"
app:layout_constraintEnd_toStartOf="@+id/playback_play_pause"
app:layout_constraintTop_toTopOf="@+id/playback_play_pause" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_play_pause"
style="@style/Widget.Auxio.Button.PlayPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_play_pause"
app:icon="@drawable/sel_playing_state_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:icon="@drawable/ic_pause_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_huge"
android:contentDescription="@string/desc_skip_next"
app:icon="@drawable/ic_skip_next_24"
app:layout_constraintBottom_toBottomOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_play_pause"
app:layout_constraintTop_toTopOf="@+id/playback_play_pause" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_shuffle"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_huge"
android:contentDescription="@string/desc_shuffle"
app:icon="@drawable/sel_shuffle_state_24"
app:iconTint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintStart_toEndOf="@+id/playback_skip_next"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next"
app:tint="@color/sel_accented" />
</androidx.constraintlayout.widget.ConstraintLayout>
</org.oxycblt.auxio.playback.ForcedLTRFrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/explore_nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.ui.BottomSheetContentBehavior"
app:navGraph="@navigation/nav_explore"
tools:layout="@layout/fragment_home" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/playback_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.playback.PlaybackSheetBehavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/playback_bar_fragment"
android:name="org.oxycblt.auxio.playback.PlaybackBarFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/playback_panel_fragment"
android:name="org.oxycblt.auxio.playback.PlaybackPanelFragment"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/queue_sheet"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="64dp"
android:text="@string/lbl_queue"
android:gravity="center"
android:textAppearance="@style/TextAppearance.Material3.LabelLarge"
android:textColor="?attr/colorOnSurfaceVariant"
app:layout_constraintBottom_toBottomOf="@+id/handle"
app:layout_constraintEnd_toEndOf="@+id/handle"
app:layout_constraintStart_toStartOf="parent" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/queue_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="org.oxycblt.auxio.playback.queue.QueueFragment" />
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,171 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback"
app:navigationIcon="@drawable/ic_down_24"
app:title="@string/lbl_playback"
tools:subtitle="@string/lbl_all_songs" />
<org.oxycblt.auxio.image.StyledImageView
android:id="@+id/playback_cover"
style="@style/Widget.Auxio.Image.Full"
android:layout_margin="@dimen/spacing_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
tools:staticIcon="@drawable/ic_song_48" />
<!-- TextView is wrapped in a container so that marquee doesn't break -->
<FrameLayout
android:id="@+id/playback_song_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_artist"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_toolbar"
app:layout_constraintVertical_chainStyle="packed">
<TextView
android:id="@+id/playback_song"
style="@style/Widget.Auxio.TextView.Primary"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:text="Song Name" />
</FrameLayout>
<TextView
android:id="@+id/playback_artist"
style="@style/Widget.Auxio.TextView.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_album"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_song_container"
tools:text="Artist Name" />
<TextView
android:id="@+id/playback_album"
style="@style/Widget.Auxio.TextView.Secondary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_seek_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_artist"
tools:text="Album Name" />
<org.oxycblt.auxio.playback.StyledSeekBar
android:id="@+id/playback_seek_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/playback_controls_container"
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" />
<org.oxycblt.auxio.playback.ForcedLTRFrameLayout
android:id="@+id/playback_controls_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_medium"
android:layout_marginEnd="@dimen/spacing_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/playback_seek_bar"
app:layout_constraintStart_toStartOf="@+id/playback_seek_bar"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_repeat"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_change_repeat"
app:icon="@drawable/ic_repeat_off_24"
app:iconTint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_prev"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/playback_skip_prev" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_skip_prev"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_skip_prev"
app:icon="@drawable/ic_skip_prev_24"
app:layout_constraintBottom_toBottomOf="@+id/playback_play_pause"
app:layout_constraintEnd_toStartOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_repeat"
app:layout_constraintTop_toTopOf="@+id/playback_play_pause" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_play_pause"
style="@style/Widget.Auxio.Button.PlayPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_play_pause"
app:icon="@drawable/sel_playing_state_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:icon="@drawable/ic_play_24" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_skip_next"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_skip_next"
app:icon="@drawable/ic_skip_next_24"
app:layout_constraintBottom_toBottomOf="@+id/playback_play_pause"
app:layout_constraintEnd_toStartOf="@+id/playback_shuffle"
app:layout_constraintStart_toEndOf="@+id/playback_play_pause"
app:layout_constraintTop_toTopOf="@+id/playback_play_pause" />
<com.google.android.material.button.MaterialButton
android:id="@+id/playback_shuffle"
style="@style/Widget.Auxio.Button.Icon.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/desc_shuffle"
app:icon="@drawable/sel_shuffle_state_24"
app:iconTint="@color/sel_accented"
app:layout_constraintBottom_toBottomOf="@+id/playback_skip_next"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/playback_skip_next"
app:tint="@color/sel_accented" />
</androidx.constraintlayout.widget.ConstraintLayout>
</org.oxycblt.auxio.playback.ForcedLTRFrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -59,6 +59,7 @@
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/queue_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lbl_queue"

View file

@ -73,7 +73,7 @@
style="@style/Widget.Auxio.Button.Icon.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/spacing_mid_medium"
android:layout_marginEnd="@dimen/spacing_small"
android:contentDescription="@string/desc_queue_handle"
app:icon="@drawable/ic_handle_24"
app:layout_constraintBottom_toBottomOf="@+id/song_album_cover"