From 9990e00a4a2d221e640d684f3ad2b6bfcd59e329 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Fri, 19 Apr 2024 11:04:24 -0600 Subject: [PATCH] playback: make bottom sheet behavior more in-spec Don't gradually fade out until the very end, reduce the corner radii at the very end, fix elevation, delift elevation at the very end. More tweaks are probably needed here to make it look good. --- .../java/org/oxycblt/auxio/MainFragment.kt | 53 +++++++++---------- .../playback/PlaybackBottomSheetBehavior.kt | 13 +++++ .../auxio/playback/PlaybackPanelFragment.kt | 2 +- .../queue/QueueBottomSheetBehavior.kt | 2 +- .../res/layout-w600dp-land/fragment_main.xml | 7 +++ app/src/main/res/layout/fragment_main.xml | 9 +++- app/src/main/res/values/dimens.xml | 2 +- 7 files changed, 57 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index da251d8df..eb5235476 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -26,13 +26,13 @@ import androidx.activity.OnBackPressedCallback import androidx.core.view.ViewCompat import androidx.core.view.isInvisible import androidx.core.view.isVisible -import androidx.core.view.updatePadding import androidx.fragment.app.activityViewModels import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import com.google.android.material.R as MR import com.google.android.material.bottomsheet.BackportBottomSheetBehavior import com.google.android.material.shape.MaterialShapeDrawable +import com.google.android.material.shape.ShapeAppearanceModel import com.google.android.material.transition.MaterialFadeThrough import com.leinardi.android.speeddial.SpeedDialOverlayLayout import dagger.hilt.android.AndroidEntryPoint @@ -62,7 +62,6 @@ import org.oxycblt.auxio.util.getDimen import org.oxycblt.auxio.util.lazyReflectedField import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.navigateSafe -import org.oxycblt.auxio.util.systemBarInsetsCompat import org.oxycblt.auxio.util.unlikelyToBeNull /** @@ -84,6 +83,7 @@ class MainFragment : private var selectionNavigationListener: DialogAwareNavigationListener? = null private var lastInsets: WindowInsets? = null private var elevationNormal = 0f + private var normalCornerSize = 0f override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -146,16 +146,22 @@ class MainFragment : // Emulate the elevated bottom sheet style. background = MaterialShapeDrawable.createWithElevationOverlay(context).apply { + val cornerSize = + context.resources.getDimension(R.dimen.size_corners_mid_large) + shapeAppearanceModel = + ShapeAppearanceModel.builder() + .setTopLeftCornerSize(cornerSize) + .setTopRightCornerSize(cornerSize) + .build() fillColor = context.getAttrColorCompat(MR.attr.colorSurfaceContainerHigh) } - // Apply bar insets for the queue's RecyclerView to use. - setOnApplyWindowInsetsListener { v, insets -> - v.updatePadding(top = insets.systemBarInsetsCompat.top) - insets - } } } + normalCornerSize = playbackSheetBehavior.sheetBackgroundDrawable.topLeftCornerResolvedSize + + binding.playbackSheet.elevation = 0f + binding.mainScrim.setOnClickListener { homeModel.setSpeedDialOpen(false) } binding.sheetScrim.setOnClickListener { homeModel.setSpeedDialOpen(false) } @@ -241,6 +247,14 @@ class MainFragment : val halfOutRatio = min(playbackRatio * 2, 1f) val halfInPlaybackRatio = max(playbackRatio - 0.5f, 0f) * 2 + val lastStretchRatio = max(playbackRatio - 0.9f, 0f) / 0.1f + + binding.mainSheetScrim.alpha = lastStretchRatio + playbackSheetBehavior.sheetBackgroundDrawable.setCornerSize( + normalCornerSize * (1 - lastStretchRatio)) + binding.exploreNavHost.isInvisible = playbackRatio == 1f + binding.playbackSheet.translationZ = (1 - lastStretchRatio) * elevationNormal + if (queueSheetBehavior != null) { // Queue sheet available, the normal transition applies, but it now much be combined // with another transition where the playback panel disappears and the playback bar @@ -263,31 +277,16 @@ class MainFragment : // No queue sheet, fade normally based on the playback sheet binding.playbackBarFragment.alpha = 1 - halfOutRatio binding.playbackPanelFragment.alpha = halfInPlaybackRatio + (binding.queueSheet.background as MaterialShapeDrawable).shapeAppearanceModel = + ShapeAppearanceModel.builder() + .setTopLeftCornerSize(normalCornerSize) + .setTopRightCornerSize(normalCornerSize * (1 - lastStretchRatio)) + .build() } - - // Fade out the content as the playback panel expands. - // TODO: Replace with shadow? - binding.exploreNavHost.apply { - alpha = outPlaybackRatio - // Prevent interactions when the content fully fades out. - isInvisible = alpha == 0f - } - - // Reduce playback sheet elevation as it expands. This involves both updating the - // shadow elevation for older versions, and fading out the background drawable - // containing the elevation overlay. - binding.playbackSheet.elevation = elevationNormal * outPlaybackRatio - playbackSheetBehavior.sheetBackgroundDrawable.alpha = (outPlaybackRatio * 255).toInt() - // Fade out the playback bar as the panel expands. binding.playbackBarFragment.apply { // Prevent interactions when the playback bar fully fades out. isInvisible = alpha == 0f - // As the playback bar expands, we also want to subtly translate the bar to - // align with the top inset. This results in both a smooth transition from the bar - // to the playback panel's toolbar, but also a correctly positioned playback bar - // for when the queue sheet expands. - lastInsets?.let { translationY = it.systemBarInsetsCompat.top * halfOutRatio } } // Prevent interactions when the playback panel fully fades out. diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBottomSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBottomSheetBehavior.kt index 37934c0e1..4a0af6d92 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBottomSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackBottomSheetBehavior.kt @@ -23,12 +23,15 @@ import android.graphics.drawable.LayerDrawable import android.util.AttributeSet import android.view.MotionEvent import android.view.View +import android.view.WindowInsets import androidx.coordinatorlayout.widget.CoordinatorLayout import com.google.android.material.R as MR import com.google.android.material.shape.MaterialShapeDrawable import org.oxycblt.auxio.R import org.oxycblt.auxio.ui.BaseBottomSheetBehavior import org.oxycblt.auxio.util.getAttrColorCompat +import org.oxycblt.auxio.util.replaceSystemBarInsetsCompat +import org.oxycblt.auxio.util.systemBarInsetsCompat /** * The [BaseBottomSheetBehavior] for the playback bottom sheet. This bottom sheet @@ -64,4 +67,14 @@ class PlaybackBottomSheetBehavior(context: Context, attributeSet: Attr fillColor = sheetBackgroundDrawable.fillColor }, sheetBackgroundDrawable)) + + override fun applyWindowInsets(child: View, insets: WindowInsets): WindowInsets { + super.applyWindowInsets(child, insets) + // Offset our expanded panel by the size of the playback bar, as that is shown when + // we slide up the panel. + val bars = insets.systemBarInsetsCompat + expandedOffset = bars.top + return insets.replaceSystemBarInsetsCompat( + bars.left, bars.top, bars.right, expandedOffset + bars.bottom) + } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt index 08befa950..eb66d5e88 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -87,7 +87,7 @@ class PlaybackPanelFragment : // --- UI SETUP --- binding.root.setOnApplyWindowInsetsListener { view, insets -> val bars = insets.systemBarInsetsCompat - view.updatePadding(top = bars.top, bottom = bars.bottom) + view.updatePadding(bottom = bars.bottom) insets } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueBottomSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueBottomSheetBehavior.kt index 24f2cfd23..6da05243f 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueBottomSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueBottomSheetBehavior.kt @@ -73,7 +73,7 @@ class QueueBottomSheetBehavior(context: Context, attributeSet: Attribu // Offset our expanded panel by the size of the playback bar, as that is shown when // we slide up the panel. val bars = insets.systemBarInsetsCompat - expandedOffset = bars.top + barHeight + barSpacing + expandedOffset = barHeight + barSpacing return insets.replaceSystemBarInsetsCompat( bars.left, bars.top, bars.right, expandedOffset + bars.bottom) } diff --git a/app/src/main/res/layout-w600dp-land/fragment_main.xml b/app/src/main/res/layout-w600dp-land/fragment_main.xml index 2b94a6958..6c900b3f9 100644 --- a/app/src/main/res/layout-w600dp-land/fragment_main.xml +++ b/app/src/main/res/layout-w600dp-land/fragment_main.xml @@ -19,6 +19,13 @@ + + + + 24dp - 6dp + 1dp 78dp 64dp