Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CollectAsState extensions for lifecycle awareness
@file:Suppress("PackageDirectoryMismatch")
package androidx.compose.runtime
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Lifecycle.State.CREATED
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.flowWithLifecycle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@Composable
fun <R> StateFlow<R>.collectAsStateWhileCreated(): State<R> =
collectAsStateWhile(minActiveState = CREATED)
@Composable
fun <R> StateFlow<R>.collectAsStateWhileStarted(): State<R> =
collectAsStateWhile(minActiveState = STARTED)
@Composable
fun <R> StateFlow<R>.collectAsStateWhile(
minActiveState: Lifecycle.State,
): State<R> = collectAsStateWhile(
minActiveState = minActiveState,
default = remember { value },
)
@Composable
fun <R> Flow<R>.collectAsStateWhileCreated(
default: R,
): State<R> = collectAsStateWhile(
minActiveState = CREATED,
default = default,
)
@Composable
fun <R> Flow<R>.collectAsStateWhileStarted(
default: R,
): State<R> = collectAsStateWhile(
minActiveState = STARTED,
default = default,
)
@Composable
fun <R> Flow<R>.collectAsStateWhile(
minActiveState: Lifecycle.State,
default: R,
): State<R> {
@Suppress("NON_EXHAUSTIVE_WHEN")
when (minActiveState) {
Lifecycle.State.INITIALIZED,
Lifecycle.State.DESTROYED -> {
throw IllegalArgumentException("Only supports lifecycle states CREATED, STARTED and RESUMED")
}
}
val lifecycleOwner = LocalLifecycleOwner.current
return remember(default, lifecycleOwner) {
flowWithLifecycle(
lifecycle = lifecycleOwner.lifecycle,
minActiveState = minActiveState,
)
}.collectAsState(initial = default)
}
package com.example
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@Composable
fun Example(
flowOfStrings: Flow<String>,
stateFlowOfStrings: StateFlow<String>,
) {
val first: String by flowOfStrings.collectAsStateWhileStarted(default = "")
val second: String by stateFlowOfStrings.collectAsStateWhileStarted()
Text(first)
Text(second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment