File tree Expand file tree Collapse file tree 3 files changed +50
-0
lines changed
samples/android/src/main/java/cafe/adriel/voyager/sample/basicNavigation
voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/lifecycle Expand file tree Collapse file tree 3 files changed +50
-0
lines changed Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment
1818import androidx.compose.ui.Modifier
1919import androidx.compose.ui.unit.dp
2020import cafe.adriel.voyager.core.lifecycle.LifecycleEffect
21+ import cafe.adriel.voyager.core.lifecycle.LifecycleEffectOnce
2122import cafe.adriel.voyager.core.screen.Screen
2223import cafe.adriel.voyager.core.screen.uniqueScreenKey
2324import cafe.adriel.voyager.navigator.LocalNavigator
@@ -36,6 +37,9 @@ data class BasicNavigationScreen(
3637 onStarted = { Log .d(" Navigator" , " Start screen #$index " ) },
3738 onDisposed = { Log .d(" Navigator" , " Dispose screen #$index " ) }
3839 )
40+ LifecycleEffectOnce {
41+ Log .d(" Navigator" , " On screen first appear #$index " )
42+ }
3943
4044 val navigator = LocalNavigator .currentOrThrow
4145
Original file line number Diff line number Diff line change 1+ package cafe.adriel.voyager.core.lifecycle
2+
3+ import cafe.adriel.voyager.core.concurrent.ThreadSafeMap
4+ import cafe.adriel.voyager.core.concurrent.ThreadSafeSet
5+ import cafe.adriel.voyager.core.screen.Screen
6+ import cafe.adriel.voyager.core.screen.ScreenKey
7+
8+ internal object LifecycleEffectStore : ScreenDisposable {
9+ private val executedLifecycles = ThreadSafeMap <ScreenKey , ThreadSafeSet <String >>()
10+
11+ fun store (screen : Screen , effectKey : String ) {
12+ val set = executedLifecycles.getOrPut(screen.key) { ThreadSafeSet () }
13+ set.add(effectKey)
14+ }
15+
16+ fun hasExecuted (screen : Screen , effectKey : String ): Boolean =
17+ executedLifecycles.get(screen.key)?.contains(effectKey) == true
18+
19+ override fun onDispose (screen : Screen ) {
20+ executedLifecycles.remove(screen.key)
21+ }
22+ }
Original file line number Diff line number Diff line change @@ -2,9 +2,16 @@ package cafe.adriel.voyager.core.lifecycle
22
33import androidx.compose.runtime.Composable
44import androidx.compose.runtime.DisposableEffect
5+ import androidx.compose.runtime.LaunchedEffect
56import androidx.compose.runtime.remember
7+ import androidx.compose.runtime.saveable.rememberSaveable
8+ import cafe.adriel.voyager.core.annotation.ExperimentalVoyagerApi
69import cafe.adriel.voyager.core.screen.Screen
10+ import cafe.adriel.voyager.core.screen.randomUuid
711
12+ @Deprecated(
13+ message = " This API is a wrap on top on DisposableEffect, will be removed in 1.1.0, replace with DisposableEffect"
14+ )
815@Composable
916public fun Screen.LifecycleEffect (
1017 onStarted : () -> Unit = {},
@@ -16,6 +23,23 @@ public fun Screen.LifecycleEffect(
1623 }
1724}
1825
26+ @ExperimentalVoyagerApi
27+ @Composable
28+ public fun Screen.LifecycleEffectOnce (onFirstAppear : () -> Unit ) {
29+ val uniqueCompositionKey = rememberSaveable { randomUuid() }
30+
31+ val lifecycleEffectStore = remember {
32+ ScreenLifecycleStore .get(this ) { LifecycleEffectStore }
33+ }
34+
35+ LaunchedEffect (Unit ) {
36+ if (lifecycleEffectStore.hasExecuted(this @LifecycleEffectOnce, uniqueCompositionKey).not ()) {
37+ lifecycleEffectStore.store(this @LifecycleEffectOnce, uniqueCompositionKey)
38+ onFirstAppear()
39+ }
40+ }
41+ }
42+
1943@Composable
2044public fun rememberScreenLifecycleOwner (
2145 screen : Screen
You can’t perform that action at this time.
0 commit comments