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

nglauber

12/16/2021, 1:57 PM
Do you know how to keep the
LazyColumn
scroll state after navigate to a different screen? I’m getting a strange behavior…
Copy code
val listState = rememberLazyListState()

val reportList by viewModel.reportList.flowInLifecycle()
    .collectAsState(initial = emptyList())
The code above is in
ScreenA
, from this screen I open
ScreenB
. When I return to
ScreenA
, the
reportsList
becomes empty for 1 composition, so the
listState
moves to position 0.
z

Zach Klippenstein (he/him) [MOD]

12/16/2021, 3:07 PM
How is
flowInLifecycle()
defined? Assuming it’s a composable that correctly remembers the transformed flow, if
viewModel.reportList
is a
StateFlow
then
flowInLifecycle
should also return a
StateFlow
so that you can use the overload of
collectAsState
that takes its initial value from the actual flow.
n

nglauber

12/16/2021, 3:09 PM
Good catch @Zach Klippenstein (he/him) [MOD]… I’ll check without it…. but here it is…
Copy code
@Composable
fun <T> Flow<T>.flowInLifecycle(): Flow<T> {
    val lifecycleOwner = LocalLifecycleOwner.current
    return remember(this, lifecycleOwner) {
        this.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
    }
}
j

JulianK

12/16/2021, 3:34 PM
I'm using a similar lifecycle aware flow collection, but for Stateflows, i use
Copy code
@Composable
fun <T> StateFlow<T>.collectAndRemember(): State<T> =
    flowInLifecycle(this).collectAsState(initial = this.value)
👍🏻 1
z

Zach Klippenstein (he/him) [MOD]

12/16/2021, 4:19 PM
Yea that
collectAndRemember
looks more like what i think you’d want
n

nglauber

12/16/2021, 6:08 PM
@JulianK, could you post your
flowInLifecycle
?
j

JulianK

12/17/2021, 8:51 AM
Should be the same as yours, actually, i changed the name to your method name in my previous comment. My whole code looks like this:
Copy code
@Composable
fun <T> rememberFlowWithLifecycle(
    flow: Flow<T>,
    lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T> = remember(flow, lifecycle) {
    flow.flowWithLifecycle(
        lifecycle = lifecycle,
        minActiveState = minActiveState
    )
}


@Composable
fun <T> StateFlow<T>.collectAndRemember(): State<T> =
    rememberFlowWithLifecycle(this).collectAsState(initial = this.value)
n

nglauber

12/17/2021, 11:29 AM
Awesome! Thanks 😉
2 Views