In Compose, a UI element with a height of 0 generally cannot receive pointer events (clicks), even if it visually scales back up later via the graphicsLayer. This commit blocks the progress from going to zero

This commit is contained in:
Vitor Pamplona
2026-02-17 16:50:43 -05:00
parent 46bc0dd750
commit 277a311fdc
@@ -28,7 +28,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.layout import androidx.compose.ui.layout.layout
import kotlin.math.roundToInt
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@@ -36,19 +35,26 @@ fun DisappearingFloatingButton(
scrollBehavior: BottomAppBarScrollBehavior, scrollBehavior: BottomAppBarScrollBehavior,
content: @Composable (BoxScope.() -> Unit), content: @Composable (BoxScope.() -> Unit),
) { ) {
// We calculate the scale/alpha based on how much the bar is expanded
// 1.0 = fully visible, 0.0 = fully hidden
val progress = (1f - scrollBehavior.state.collapsedFraction).coerceAtLeast(0.001f)
Box( Box(
modifier = modifier =
Modifier Modifier
.layout { measurable, constraints -> .layout { measurable, constraints ->
val placeable = measurable.measure(constraints) val placeable = measurable.measure(constraints)
val height = placeable.height * (1 - scrollBehavior.state.collapsedFraction) // Adjust the height of the layout so the FAB doesn't leave a "hole"
layout(placeable.width, height.roundToInt().coerceAtLeast(0)) { val currentHeight = (placeable.height * progress).toInt()
placeable.place(0, 0) layout(placeable.width, currentHeight) {
placeable.placeRelative(0, 0)
} }
}.graphicsLayer { }.graphicsLayer {
val percentage = 1 - scrollBehavior.state.collapsedFraction this.scaleX = progress
this.scaleX = percentage this.scaleY = progress
this.scaleY = percentage this.alpha = progress
// Clip the content as it shrinks to prevent overflow
clip = true
}, },
content = content, content = content,
) )