Pick the fix
Scrolling recomposes Screen on every frame. Which change keeps composition out of it?
@Composable
fun Screen(items: List<String>) {
val listState = rememberLazyListState()
Box {
LazyColumn(state = listState) { items(items) { Text(it) } }
Text("Header",
Modifier.offset(y = (-listState.firstVisibleItemScrollOffset).dp))
}
}Hint 1 of 1
In which phase is the offset value read?
Choose an answer, then open Show answer below to check it.
Show answer
Answer: A Use Modifier.offset { IntOffset(0, -listState.firstVisibleItemScrollOffset) }
Correct. The lambda is read in the layout phase, so composition doesn't re-run.
Why not the others?
- B Wrap the offset in
remember. remember caches one value and the header would stop moving. - C Use
derivedStateOffor the offset. That helps when you only need a coarser value; here the exact offset changes every frame. - D Move the header into a LazyColumn item. That changes the layout, not where the state is read.
Illustrative, based on Compose and Android rules; not a device recording
Text version
| Composable | offset(y = ...) | offset { ... } |
|---|---|---|
Screen | 60 recompositions | 0: skipped |
LazyColumn | 0: skipped | 0: skipped |
Header | 60 recompositions | 0: skipped |