Last active
March 10, 2022 17:26
-
-
Save Aidanvii7/1eb5d919a60a5441a6ec05e6f3f2de8d to your computer and use it in GitHub Desktop.
compose utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.MutableState | |
import androidx.compose.runtime.State | |
import androidx.compose.runtime.collectAsState | |
import androidx.compose.runtime.remember | |
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.MutableStateFlow | |
import kotlinx.coroutines.flow.StateFlow | |
import kotlinx.coroutines.flow.flow | |
@Composable | |
fun <T> StateFlow<T>.collectAsStateWhileCreated(): State<T> = | |
collectAsStateWhile(minActiveState = CREATED) | |
@Composable | |
fun <T> StateFlow<T>.collectAsStateWhileStarted(): State<T> = | |
collectAsStateWhile(minActiveState = STARTED) | |
@Composable | |
fun <T> MutableStateFlow<T>.collectAsMutableStateWhileCreated(): MutableState<T> = | |
collectAsMutableStateWhile(minActiveState = CREATED) | |
@Composable | |
fun <T> MutableStateFlow<T>.collectAsMutableStateWhileStarted(): MutableState<T> = | |
collectAsMutableStateWhile(minActiveState = STARTED) | |
@Composable | |
fun <T> StateFlow<T>.collectAsStateWhile( | |
minActiveState: Lifecycle.State, | |
): State<T> = collectAsStateWhile( | |
minActiveState = minActiveState, | |
default = remember { value }, | |
) | |
@Composable | |
fun <T> MutableStateFlow<T>.collectAsMutableStateWhile( | |
minActiveState: Lifecycle.State, | |
): MutableState<T> = collectAsMutableStateWhile( | |
minActiveState = minActiveState, | |
default = remember { value }, | |
) | |
@Composable | |
fun <T> Flow<T>.collectAsStateWhileCreated( | |
default: T, | |
): State<T> = collectAsStateWhile( | |
minActiveState = CREATED, | |
default = default, | |
) | |
@Composable | |
fun <T> Flow<T>.collectAsStateWhileStarted( | |
default: T, | |
): State<T> = collectAsStateWhile( | |
minActiveState = STARTED, | |
default = default, | |
) | |
@Composable | |
fun <T> Flow<T>.collectAsStateWhile( | |
minActiveState: Lifecycle.State, | |
default: T, | |
): State<T> { | |
@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(this, default, lifecycleOwner) { | |
flowWithLifecycle( | |
lifecycle = lifecycleOwner.lifecycle, | |
minActiveState = minActiveState, | |
) | |
}.collectAsState(initial = default) | |
} | |
@Composable | |
fun <T> MutableStateFlow<T>.collectAsMutableStateWhile( | |
minActiveState: Lifecycle.State, | |
default: T, | |
): MutableState<T> { | |
@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 | |
val state: State<T> = remember(this, default, lifecycleOwner) { | |
flowWithLifecycle( | |
lifecycle = lifecycleOwner.lifecycle, | |
minActiveState = minActiveState, | |
) | |
}.collectAsState(initial = default) | |
val mutableState: MutableState<T> = remember(state) { | |
object : MutableState<T> { | |
override var value: T | |
get() = state.value | |
set(value) { | |
[email protected] = value | |
} | |
override operator fun component1(): T = value | |
override operator fun component2(): (T) -> Unit = { value = it } | |
} | |
} | |
return mutableState | |
} | |
@Composable | |
fun <T> (suspend () -> T).asStateWhileCreated( | |
default: T, | |
): State<T> = asStateWhile( | |
minActiveState = CREATED, | |
default = default, | |
) | |
@Composable | |
fun <T> (suspend () -> T).asStateWhileStarted( | |
default: T, | |
): State<T> = asStateWhile( | |
minActiveState = STARTED, | |
default = default, | |
) | |
@Composable | |
fun <T> (suspend () -> T).asStateWhile( | |
minActiveState: Lifecycle.State, | |
default: T, | |
): State<T> = remember(this) { | |
flow { | |
val value: T = invoke() | |
emit(value) | |
} | |
}.collectAsStateWhile( | |
minActiveState = minActiveState, | |
default = default, | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.DisallowComposableCalls | |
import androidx.compose.runtime.MutableState | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import java.util.concurrent.atomic.AtomicBoolean | |
@Composable | |
inline fun <T> rememberMutable( | |
calculation: @DisallowComposableCalls () -> T, | |
): MutableState<T> = remember { mutableStateOf(calculation()) } | |
@Composable | |
inline fun <T> rememberMutable( | |
key: Any?, | |
calculation: @DisallowComposableCalls () -> T, | |
): MutableState<T> { | |
val current: MutableState<T> = remember { mutableStateOf(calculation()) } | |
val firstRun: AtomicBoolean = remember { AtomicBoolean(true) } | |
remember<Any?>(key) { | |
if (firstRun.getAndSet(false)) return@remember | |
current.value = calculation() | |
} | |
return current | |
} | |
@Composable | |
inline fun <T> rememberMutable( | |
key1: Any?, | |
key2: Any?, | |
calculation: @DisallowComposableCalls () -> T, | |
): MutableState<T> { | |
val current: MutableState<T> = remember { mutableStateOf(calculation()) } | |
val firstRun: AtomicBoolean = remember { AtomicBoolean(true) } | |
remember<Any?>(key1, key2) { | |
if (firstRun.getAndSet(false)) return@remember | |
current.value = calculation() | |
} | |
return current | |
} | |
@Composable | |
inline fun <T> rememberMutable( | |
key1: Any?, | |
key2: Any?, | |
key3: Any?, | |
calculation: @DisallowComposableCalls () -> T, | |
): MutableState<T> { | |
val current: MutableState<T> = remember { mutableStateOf(calculation()) } | |
val firstRun: AtomicBoolean = remember { AtomicBoolean(true) } | |
remember<Any?>(key1, key2, key3) { | |
if (firstRun.getAndSet(false)) return@remember | |
current.value = calculation() | |
} | |
return current | |
} | |
@Composable | |
inline fun <T> rememberMutable( | |
vararg keys: Any?, | |
calculation: @DisallowComposableCalls () -> T, | |
): MutableState<T> { | |
val current: MutableState<T> = remember { mutableStateOf(calculation()) } | |
val firstRun: AtomicBoolean = remember { AtomicBoolean(true) } | |
remember<Any?>(*keys) { | |
if (firstRun.getAndSet(false)) return@remember | |
current.value = calculation() | |
} | |
return current | |
} | |
@Composable | |
inline fun <T, R> T.remembered( | |
calculation: @DisallowComposableCalls T.() -> R, | |
): R = remember(this) { | |
calculation() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment