https://kotlinlang.org logo
#compose
Title
# compose
t

Tom De Decker

10/13/2023, 8:58 AM
Does anyone know if there's any recommended way to change a ScrollState outside of a composition? In my case the activity hosting the screen composable can receive an intent telling it to scroll back up. From what I've tried, it seems to be illegal to directly call the animateScrollToPosition function on the ScrollState outside the composition scope. My next guess would be to have a flow of events inside the activity or viewmodel which the composable could then collect but I'm not sure whether this is ideal.
z

Zach Klippenstein (he/him) [MOD]

10/13/2023, 1:04 PM
I believe you just need to call it on a scope that has a frame clock. You can probably bring the frame clock from a composable scope, but this sounds fishy. Anywhere that you’re creating a compose scroll state should probably also be able to get access to a coroutine scope directly from compose somehow.
Would need to see your code to say more
t

Tom De Decker

10/13/2023, 1:16 PM
Right, I agree that messing around with these coroutine scopes feels a little too fishy. I've currently solved it using a SharedFlow of events going from Activity -> ViewModel -> Composable on which I post an event requesting a scroll and that seems to work fine. Maybe a little overkill for the job but should other similar situations arise I can always just add an event. Something like this:
Copy code
@Composable
fun MyComposable(viewModel: MyViewModel) {
    val event by viewModel.events.collectAsState()
    val scrollState = rememberScrollState()
    
    LaunchedEffect(event) {
        is Event.ScrollToTop -> scrollState.animateScrollToPosition(0)
    }
    
    // ...
}
Thanks for taking the time to answer!
z

Zach Klippenstein (he/him) [MOD]

10/13/2023, 1:18 PM
I would simplify that further, and get composition out of your event pipeline, by launching a single effect and collecting the event flow in there.
1
t

Tom De Decker

10/13/2023, 1:19 PM
I forgot that was an option, good call!