playback: improve compact -> full transition

Improve the way the compact playback view transforms into the full
playback view by splitting their view animations in two. This makes
the transition more akin to the Android 12 notification menu, which
due to the nature of how I'm fading views really does make it more
user friendly. Also re-add the "Now Playing" title and a new subtitle
displaying the currently playing artist.
This commit is contained in:
OxygenCobalt 2021-11-25 09:04:22 -07:00
parent 4ccaa7c4bb
commit 805035f0d8
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
6 changed files with 35 additions and 18 deletions

View file

@ -109,6 +109,14 @@ class PlaybackFragment : Fragment() {
} }
} }
playbackModel.parent.observe(viewLifecycleOwner) { parent ->
if (parent != null) {
binding.playbackToolbar.subtitle = parent.resolvedName
} else {
binding.playbackToolbar.setSubtitle(R.string.lbl_all_songs)
}
}
playbackModel.isShuffling.observe(viewLifecycleOwner) { isShuffling -> playbackModel.isShuffling.observe(viewLifecycleOwner) { isShuffling ->
binding.playbackShuffle.isActivated = isShuffling binding.playbackShuffle.isActivated = isShuffling
} }

View file

@ -527,24 +527,28 @@ class PlaybackLayout @JvmOverloads constructor(
} }
/** /**
* Update the view transitions done when the panel slides up. * Do the nice view animations that occur whenever we slide up the playback panel.
* The way I transition is largely inspired by Android 12's notification panel, with the
* compact view fading out completely before the panel view fades in. We don't fade out the
* content though so we have cohesion between the other sliding transitions.
*/ */
private fun updatePanelTransition() { private fun updatePanelTransition() {
val outAlpha = min(1 - panelOffset, 1f) val ratio = max(panelOffset, 0f)
val inAlpha = max(panelOffset, 0f)
contentView.apply { val outRatio = 1 - ratio
alpha = outAlpha val halfOutRatio = min(ratio / 0.5f, 1f)
isInvisible = alpha == 0f val halfInRatio = max(ratio - 0.5f, 0f) / 0.5f
}
// Optimize out drawing for this view completely
contentView.isInvisible = outRatio == 0f
// Slowly reduce the elevation as we slide up, eventually resulting in a neutral color // Slowly reduce the elevation as we slide up, eventually resulting in a neutral color
// instead of an elevated one when fully expanded. // instead of an elevated one when fully expanded.
(playbackContainerView.background as MaterialShapeDrawable).alpha = (outAlpha * 255).toInt() (playbackContainerView.background as MaterialShapeDrawable).alpha = (outRatio * 255).toInt()
// Fade out our bar view as we slide up // Fade out our bar view as we slide up
playbackBarView.apply { playbackBarView.apply {
alpha = outAlpha alpha = min(1 - halfOutRatio, 1f)
isInvisible = alpha == 0f isInvisible = alpha == 0f
// When edge-to-edge is enabled, the playback bar will not fade out into the // When edge-to-edge is enabled, the playback bar will not fade out into the
@ -561,7 +565,7 @@ class PlaybackLayout @JvmOverloads constructor(
params.setMargins( params.setMargins(
params.leftMargin, params.leftMargin,
(bars.top * max(panelOffset, 0f)).toInt(), (bars.top * halfOutRatio).toInt(),
params.rightMargin, params.rightMargin,
params.bottomMargin params.bottomMargin
) )
@ -575,7 +579,7 @@ class PlaybackLayout @JvmOverloads constructor(
// Fade in our panel as we slide up // Fade in our panel as we slide up
playbackPanelView.apply { playbackPanelView.apply {
alpha = inAlpha alpha = halfInRatio
isInvisible = alpha == 0f isInvisible = alpha == 0f
} }
} }
@ -587,10 +591,11 @@ class PlaybackLayout @JvmOverloads constructor(
(computePanelTopPosition(0f) - topPosition).toFloat() / panelRange (computePanelTopPosition(0f) - topPosition).toFloat() / panelRange
private fun smoothSlideTo(offset: Float) { private fun smoothSlideTo(offset: Float) {
// Find the new top position and animate the panel to that val okay = dragHelper.smoothSlideViewTo(
val panelTop = computePanelTopPosition(offset) playbackContainerView, playbackContainerView.left, computePanelTopPosition(offset)
)
if (dragHelper.smoothSlideViewTo(playbackContainerView, playbackContainerView.left, panelTop)) { if (okay) {
postInvalidateOnAnimation() postInvalidateOnAnimation()
} }
} }

View file

@ -26,11 +26,12 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"> android:clipToPadding="false">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Auxio.Toolbar.Icon.Down" style="@style/Widget.Auxio.Toolbar.Icon.Down"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:title="@string/info_widget_name"
app:menu="@menu/menu_playback" /> app:menu="@menu/menu_playback" />
<ImageView <ImageView

View file

@ -26,10 +26,11 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"> android:clipToPadding="false">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Auxio.Toolbar.Icon.Down" style="@style/Widget.Auxio.Toolbar.Icon.Down"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:title="@string/info_widget_name"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback" /> app:menu="@menu/menu_playback" />

View file

@ -26,11 +26,12 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"> android:clipToPadding="false">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Auxio.Toolbar.Icon.Down" style="@style/Widget.Auxio.Toolbar.Icon.Down"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:title="@string/info_widget_name"
app:menu="@menu/menu_playback" /> app:menu="@menu/menu_playback" />
<ImageView <ImageView

View file

@ -25,11 +25,12 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"> android:clipToPadding="false">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Auxio.Toolbar.Icon.Down" style="@style/Widget.Auxio.Toolbar.Icon.Down"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:title="@string/info_widget_name"
app:menu="@menu/menu_playback" /> app:menu="@menu/menu_playback" />
<ImageView <ImageView