0

I need to listen to the scroll values of a Column and post the value to the view model. This works with a LaunchedEffect, but it causes recomposition on each new scroll value. The code looks something like this:

val scrollState = rememberScrollState(0)

LaunchedEffect(scrollState.value) {
    Log.d(TAG, "Scrolled to ${scrollState.value}")
}

Column(modifier = Modifier.scrollable(scrollState)) {
    ...
}

How can I react to scrolling without recomposition happening?

manabreak
  • 5,415
  • 7
  • 39
  • 96
  • check also https://stackoverflow.com/q/69128743/2016562 – Gabriele Mariotti Nov 09 '22 at 07:34
  • @GabrieleMariotti AFAIK the solutions provided there all cause recomposition. – manabreak Nov 09 '22 at 07:46
  • maybe because the viewmodel is changing some other state causing recomposition – zjmo Nov 09 '22 at 11:58
  • @zjmo That's what I originally thought, but no. If I comment out the LaunchedEffect part of the code, there's no recomposition happening. It's enough to just have that LaunchedEffect there to trigger recomposition on each new scroll value. – manabreak Nov 09 '22 at 12:54
  • try with val scroll by remember{derivedStateOf{ scrollState.value > 10 }}, this way it only triggers when the value cross 10. Depending on your needsm change the expression in derived state. Then launch the sideeffect when value scroll changes – zjmo Nov 09 '22 at 13:25
  • @zjmo That would result in different logic. I need to emit each and every scroll value as the scrolling happens. – manabreak Nov 10 '22 at 06:00
  • I would suggest not treating `re-composition` as something vile the you have to avoid at any cost (which I'm trying to appreciate recently) , you said "I want to listen" - any composable that listens to an observed state will always re-compose, especially in your case because you want to observe "EACH" scroll value, you have to be specific WHICH PART you don't want to recompose. – z.g.y Nov 10 '22 at 06:10
  • I would also suggest visiting Philipp Lackner, he just released a new YouTube video about compose performance, you can check it out. You can also check Thracian's answer here. https://stackoverflow.com/questions/74361197/jetpack-compose-avoid-unnecessary-recomposition about deferring states – z.g.y Nov 10 '22 at 06:10
  • @manabreak got it, really depends on where you see recomposition happening, z.y gave you a good hint, anyway try to switch to LazyColumn with indexed elements should already improve – zjmo Nov 10 '22 at 07:49
  • @z.y I would be happy if only the relevant portion of the code got recomposed if needed. However, the whole structure gets recomposed, which causes notable lagging when scrolling. I'm a bit baffled on why reading a value would cause recomposition when it's not used to update anything. – manabreak Nov 10 '22 at 08:50
  • leaving a mutable state inside a composable is enough to trigger a recomposition when its state changes whether you are using it or not, there's actually a question here in S.O where someone asked why there's a `LocalConfiguration.current` in a middle of a composable that's not even used anywhere in it based on NowInAndroid repo project. – z.g.y Nov 11 '22 at 07:55
  • this https://stackoverflow.com/questions/74089871/jetpack-compose-localcomposition-current/74102299#74102299 – z.g.y Nov 11 '22 at 07:56

0 Answers0