Nthily
08/07/2023, 5:02 AMonPreFling
method in NestedScrollConnection
? I'm trying to create a nested layout, but I'm encountering some strange issues. 🙏
During the onPreScroll
or onPostScroll
process, if it's not a fast fling or if I try to scroll by dragging, the nested layout doesn't scroll properly. 🤔Nthily
08/07/2023, 5:02 AM@Composable
internal fun CollapsingLayout(
collapsingTop: @Composable BoxScope.() -> Unit,
bodyContent: @Composable BoxScope.() -> Unit,
topBar: @Composable (Float) -> Unit,
modifier: Modifier = Modifier,
) {
var collapsingTopHeight by remember { mutableFloatStateOf(0f) }
var topBarHeight by remember { mutableFloatStateOf(0f) }
var topBarAlpha by remember { mutableFloatStateOf(0f) }
var offset by remember { mutableFloatStateOf(0f) }
fun calculateOffset(delta: Float): Offset {
val oldOffset = offset
val newOffset = (oldOffset + delta).coerceIn(-(collapsingTopHeight-topBarHeight), 0f)
offset = newOffset
topBarAlpha = abs(offset / (collapsingTopHeight - topBarHeight))
return Offset(0f, newOffset - oldOffset)
}
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
return when {
available.y >= 0 -> Offset.Zero
else -> calculateOffset(available.y)
}
}
override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource,
): Offset {
return when {
available.y <= 0 -> Offset.Zero
else -> calculateOffset(available.y)
}
}
}
}
Box(
modifier = modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection),
) {
Box(
modifier = Modifier
.onSizeChanged { size ->
collapsingTopHeight = size.height.toFloat()
}
.offset { IntOffset(x = 0, y = offset.roundToInt()) },
content = collapsingTop,
)
Box(
modifier = Modifier.offset {
IntOffset(
x = 0,
y = (collapsingTopHeight + offset).roundToInt()
)
},
content = bodyContent,
)
Box(
modifier = Modifier
.onSizeChanged {
topBarHeight = it.height.toFloat()
},
) {
topBar(topBarAlpha)
}
}
}
Nazar Rusnak
08/07/2023, 8:31 AMCompositionLocalProvider(
LocalOverscrollConfiguration provides null,
content = {
// Screen content
}
)
Nthily
08/07/2023, 8:36 AMonPreFling
method inside the NestedScollConnection
Nazar Rusnak
08/07/2023, 8:40 AMNthily
08/07/2023, 8:42 AMNthily
08/07/2023, 8:46 AMMax Oliynick
08/07/2023, 9:19 AMjossiwolf
08/07/2023, 9:48 AMAlbert Chang
08/07/2023, 2:53 PMfun calculateOffset(delta: Float): Offset {
...
val consumed = newOffset - oldOffset
return Offset(0f, if (abs(consumed - available) < Epsilon) available else consumed)
}
// Elsewhere in the file
private const val Epsilon = 1e-4f
Nthily
08/11/2023, 4:03 AMonPostScroll
. It cannot directly slide me from LazyColumn to the top, and I must wait for the LazyColumn to slide to the end before dragging again to reach the top. Do you know what caused this?Nthily
08/11/2023, 4:07 AMAlbert Chang
08/11/2023, 5:41 AM