@@ -23,20 +23,23 @@ import androidx.compose.ui.unit.dp
2323@Stable
2424internal class CollapsibleHeaderState (
2525 private val density : Density ,
26- val stickyHeaderHeightDp : Dp ,
26+ val initialStickyHeaderHeightDp : Dp ,
2727 val expandedHeaderHeightDp : Dp ,
2828) {
29- private val stickyHeaderHeightPx: Float = with (density) { stickyHeaderHeightDp.toPx() }
30-
3129 private val expandedHeaderHeightPx: Float = with (density) { expandedHeaderHeightDp.toPx() }
30+ private val initialStickyHeaderHeightPx: Float = with (density) { initialStickyHeaderHeightDp.toPx() }
31+
32+ var stickyHeaderActualBottomPx by mutableFloatStateOf(initialStickyHeaderHeightPx)
33+ internal set
3234
33- val collapsedContentOffsetDp: Dp = with (density) { stickyHeaderHeightPx.toDp() + 18 .dp }
35+ val collapsedContentOffsetDp: Dp
36+ get() = with (density) { stickyHeaderActualBottomPx.toDp() }
3437
3538 var currentHeightPx by mutableFloatStateOf(expandedHeaderHeightPx)
3639 private set
3740
3841 val expansionProgress: Float
39- get() = if (expandedHeaderHeightPx > 0f ) ( currentHeightPx / expandedHeaderHeightPx).coerceIn(0f , 1f ) else 1f
42+ get() = ( currentHeightPx / expandedHeaderHeightPx).coerceIn(0f , 1f )
4043
4144 val nestedScrollConnection = object : NestedScrollConnection {
4245 override fun onPreScroll (available : Offset , source : NestedScrollSource ) =
@@ -46,33 +49,22 @@ internal class CollapsibleHeaderState(
4649 if (available.y > 0 ) consumeDelta(available.y) else Offset .Zero
4750
4851 override suspend fun onPreFling (available : Velocity ): Velocity {
49- if (currentHeightPx <= 0f || currentHeightPx >= expandedHeaderHeightPx) return Velocity .Zero
52+ val isFullyCollapsed = currentHeightPx < 1f
53+ val isFullyExpanded = currentHeightPx > expandedHeaderHeightPx - 1f
5054
51- val collapse = 0f
52- val expand = expandedHeaderHeightPx
55+ if (isFullyCollapsed || isFullyExpanded) return Velocity .Zero
5356
5457 val target = when {
55- available.y < - 50f -> collapse
56- available.y > 50f -> expand
57- else -> if (currentHeightPx - collapse < expand - currentHeightPx) collapse else expand
58+ available.y < - 50f -> 0f
59+ available.y > 50f -> expandedHeaderHeightPx
60+ else -> if (currentHeightPx < expandedHeaderHeightPx / 2 ) 0f else expandedHeaderHeightPx
5861 }
5962
6063 snapTo(targetHeight = target, velocity = available.y)
61-
62- return Velocity (0f , available.y)
64+ return Velocity .Zero
6365 }
6466
6567 override suspend fun onPostFling (consumed : Velocity , available : Velocity ): Velocity {
66- if (available.y > 0 && currentHeightPx < expandedHeaderHeightPx) {
67- snapTo(targetHeight = expandedHeaderHeightPx, velocity = available.y)
68- return Velocity (0f , available.y)
69- }
70-
71- if (available.y < 0 && currentHeightPx > 0f ) {
72- snapTo(targetHeight = 0f , velocity = available.y)
73- return Velocity (0f , available.y)
74- }
75-
7668 return Velocity .Zero
7769 }
7870 }
@@ -94,27 +86,25 @@ internal class CollapsibleHeaderState(
9486 dampingRatio = Spring .DampingRatioNoBouncy ,
9587 stiffness = Spring .StiffnessMediumLow ,
9688 ),
97- ) { value, _ ->
98- currentHeightPx = value
99- }
89+ ) { value, _ -> currentHeightPx = value.coerceIn(0f , expandedHeaderHeightPx) }
10090 }
10191}
10292
10393@Composable
10494internal fun rememberCollapsibleHeaderState (
10595 density : Density = LocalDensity .current,
10696 windowInfo : WindowInfo = LocalWindowInfo .current,
107- stickyHeaderHeight : Dp = 48.dp,
97+ initialStickyHeaderHeightDp : Dp = 48.dp,
10898 minExpandedHeaderHeight : Dp = 146.dp,
10999): CollapsibleHeaderState {
110100 val containerSize = windowInfo.containerSize
111- return remember(density, containerSize, minExpandedHeaderHeight, stickyHeaderHeight ) {
101+ return remember(density, containerSize, minExpandedHeaderHeight, initialStickyHeaderHeightDp ) {
112102 val screenHeightDp = with (density) { containerSize.height.toDp() }
113103 val expandedHeaderHeightDp = (screenHeightDp * 0.18f ).coerceAtLeast(minExpandedHeaderHeight)
114104
115105 CollapsibleHeaderState (
116106 density = density,
117- stickyHeaderHeightDp = stickyHeaderHeight ,
107+ initialStickyHeaderHeightDp = initialStickyHeaderHeightDp ,
118108 expandedHeaderHeightDp = expandedHeaderHeightDp,
119109 )
120110 }
0 commit comments