From 1d259ebaa6da645c69bb1aee54b9d5aa278ef31b Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Mon, 25 Jul 2022 13:12:52 +0200 Subject: [PATCH] Fix BottomSheet behaviour on configuration change (regression of #457e6712) --- .../it/vfsfitvnm/vimusic/MainActivity.kt | 4 +- .../vimusic/ui/components/BottomSheet.kt | 74 ++++++++++--------- .../vfsfitvnm/vimusic/ui/views/PlayerView.kt | 4 +- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt index 21bfdd3..d33dcdb 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt @@ -216,9 +216,9 @@ class MainActivity : ComponentActivity() { when (val uri = uri) { null -> { val playerBottomSheetState = rememberBottomSheetState( - lowerBound = 0.dp, + dismissedBound = 0.dp, collapsedBound = Dimensions.collapsedPlayer, - upperBound = maxHeight, + expandedBound = maxHeight, isExpanded = expandPlayerBottomSheet ) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt index 7bccdf1..8481617 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt @@ -52,14 +52,14 @@ fun BottomSheet( modifier: Modifier = Modifier, peekHeight: Dp = 0.dp, elevation: Dp = 8.dp, - onSwiped: (() -> Unit)? = null, + onDismiss: (() -> Unit)? = null, collapsedContent: @Composable BoxScope.() -> Unit, content: @Composable BoxScope.() -> Unit ) { Box( modifier = modifier .offset { - val y = (state.upperBound - state.value + peekHeight) + val y = (state.expandedBound - state.value + peekHeight) .roundToPx() .coerceAtLeast(0) IntOffset(x = 0, y = y) @@ -87,25 +87,25 @@ fun BottomSheet( if (velocity.absoluteValue > 300 && initialValue != state.value) { when (initialValue) { - state.upperBound -> state.collapse() - state.collapsedBound -> if (initialValue > state.value && onSwiped != null) { - state.swipe() - onSwiped.invoke() + state.expandedBound -> state.collapse() + state.collapsedBound -> if (initialValue > state.value && onDismiss != null) { + state.dismiss() + onDismiss.invoke() } else { state.expand() } } } else { - val l0 = state.lowerBound - val l1 = (state.collapsedBound - state.lowerBound) / 2 - val l2 = (state.upperBound - state.collapsedBound) / 2 - val l3 = state.upperBound + val l0 = state.dismissedBound + val l1 = (state.collapsedBound - state.dismissedBound) / 2 + val l2 = (state.expandedBound - state.collapsedBound) / 2 + val l3 = state.expandedBound when (state.value) { in l0..l1 -> { - if (onSwiped != null) { - state.swipe() - onSwiped.invoke() + if (onDismiss != null) { + state.dismiss() + onDismiss.invoke() } else { state.collapse() } @@ -126,7 +126,7 @@ fun BottomSheet( content() } - if (!state.isExpanded && (onSwiped == null || !state.isDismissed)) { + if (!state.isExpanded && (onDismiss == null || !state.isDismissed)) { Box( modifier = Modifier .graphicsLayer { @@ -150,13 +150,13 @@ class BottomSheetState( draggableState: DraggableState, private val coroutineScope: CoroutineScope, private val animatable: Animatable, - private val onWasExpandedChanged: (Boolean) -> Unit, + private val onAnchorChanged: (Int) -> Unit, val collapsedBound: Dp, ) : DraggableState by draggableState { - val lowerBound: Dp + val dismissedBound: Dp get() = animatable.lowerBound!! - val upperBound: Dp + val expandedBound: Dp get() = animatable.upperBound!! val value by animatable.asState() @@ -178,14 +178,14 @@ class BottomSheetState( } private fun collapse(animationSpec: AnimationSpec) { - onWasExpandedChanged(false) + onAnchorChanged(collapsedAnchor) coroutineScope.launch { animatable.animateTo(collapsedBound, animationSpec) } } fun expand(animationSpec: AnimationSpec) { - onWasExpandedChanged(true) + onAnchorChanged(expandedAnchor) coroutineScope.launch { animatable.animateTo(animatable.upperBound!!, animationSpec) } @@ -207,8 +207,8 @@ class BottomSheetState( expand(tween(300)) } - fun swipe() { - onWasExpandedChanged(false) + fun dismiss() { + onAnchorChanged(dismissedAnchor) coroutineScope.launch { animatable.animateTo(animatable.lowerBound!!) } @@ -277,24 +277,34 @@ class BottomSheetState( } } +private const val expandedAnchor = 2 +private const val collapsedAnchor = 1 +private const val dismissedAnchor = 0 + @Composable fun rememberBottomSheetState( - lowerBound: Dp, - upperBound: Dp, - collapsedBound: Dp = lowerBound, + dismissedBound: Dp, + expandedBound: Dp, + collapsedBound: Dp = dismissedBound, isExpanded: Boolean = false ): BottomSheetState { val density = LocalDensity.current val coroutineScope = rememberCoroutineScope() - var wasExpanded by rememberSaveable { - mutableStateOf(isExpanded) + var previousAnchor by rememberSaveable { + mutableStateOf(if (isExpanded) expandedAnchor else collapsedAnchor) } - return remember(lowerBound, upperBound, collapsedBound, coroutineScope) { - val animatable = - Animatable(if (wasExpanded) upperBound else lowerBound, Dp.VectorConverter).also { - it.updateBounds(lowerBound.coerceAtMost(upperBound), upperBound) + return remember(dismissedBound, expandedBound, collapsedBound, coroutineScope) { + val initialValue = when (previousAnchor) { + expandedAnchor -> expandedBound + collapsedAnchor -> collapsedBound + dismissedAnchor -> dismissedBound + else -> error("Unknown BottomSheet anchor") + } + + val animatable = Animatable(initialValue, Dp.VectorConverter).also { + it.updateBounds(dismissedBound.coerceAtMost(expandedBound), expandedBound) } BottomSheetState( @@ -303,9 +313,7 @@ fun rememberBottomSheetState( animatable.snapTo(animatable.value - with(density) { delta.toDp() }) } }, - onWasExpandedChanged = { - wasExpanded = it - }, + onAnchorChanged = { previousAnchor = it }, coroutineScope = coroutineScope, animatable = animatable, collapsedBound = collapsedBound diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt index 610c049..1469dea 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt @@ -147,7 +147,7 @@ fun PlayerView( BottomSheet( state = layoutState, modifier = modifier, - onSwiped = binder.player::clearMediaItems, + onDismiss = binder.player::clearMediaItems, collapsedContent = { Row( horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -315,7 +315,7 @@ fun PlayerView( } PlayerBottomSheet( - layoutState = rememberBottomSheetState(64.dp, layoutState.upperBound), + layoutState = rememberBottomSheetState(64.dp, layoutState.expandedBound), isShowingLyrics = isShowingLyrics, onShowLyrics = { isShowingStatsForNerds = false