From 622c585d9846b88cfea31877963f665e5ed7e2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adriel=20Caf=C3=A9?= Date: Wed, 25 Aug 2021 19:23:19 -0300 Subject: [PATCH] fix: add support for SavedStateHandle --- gradle.properties | 2 +- gradle/libs.versions.toml | 3 ++ .../sample/androidNavigation/DetailsScreen.kt | 2 +- .../BasicNavigationActivity.kt | 9 +--- .../basicNavigation/BasicNavigationScreen.kt | 6 +-- voyager-androidx/build.gradle | 2 + .../adriel/voyager/androidx/AndroidScreen.kt | 5 +-- .../voyager/androidx/ScreenLifecycleOwner.kt | 41 +++++++++++++++++++ .../voyager/androidx/ViewModelStoreOwner.kt | 19 --------- 9 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ScreenLifecycleOwner.kt delete mode 100644 voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ViewModelStoreOwner.kt diff --git a/gradle.properties b/gradle.properties index 7d4a428b..cee740c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ kotlin.code.style=official # Maven GROUP=cafe.adriel.voyager -VERSION_NAME=1.0.0-beta07 +VERSION_NAME=1.0.0-beta08 POM_DESCRIPTION=A pragmatic navigation library for Jetpack Compose POM_INCEPTION_YEAR=2021 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c3e980f1..3239b218 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ plugin-maven = "0.17.0" kotlin = "1.5.21" koin = "3.1.2" appCompat = "1.3.1" +lifecycle = "2.4.0-alpha03" compose = "1.1.0-alpha02" composeActivity = "1.3.1" composeViewModel = "1.0.0-alpha07" @@ -20,6 +21,8 @@ plugin-maven = { module = "com.vanniktech:gradle-maven-publish-plugin", version. koin = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koin" } appCompat = { module = "androidx.appcompat:appcompat", version.ref = "appCompat" } +lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" } +lifecycle-savedState = { module = "androidx.lifecycle:lifecycle-viewmodel-savedstate", version.ref = "lifecycle" } compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "compose" } compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } compose-runtimeSaveable = { module = "androidx.compose.runtime:runtime-saveable", version.ref = "compose" } diff --git a/sample/src/main/java/cafe/adriel/voyager/sample/androidNavigation/DetailsScreen.kt b/sample/src/main/java/cafe/adriel/voyager/sample/androidNavigation/DetailsScreen.kt index b012e909..3bb9ea8c 100644 --- a/sample/src/main/java/cafe/adriel/voyager/sample/androidNavigation/DetailsScreen.kt +++ b/sample/src/main/java/cafe/adriel/voyager/sample/androidNavigation/DetailsScreen.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.unit.dp import cafe.adriel.voyager.androidx.AndroidScreen import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow -import org.koin.androidx.viewmodel.ext.android.getViewModel +import org.koin.androidx.compose.getViewModel import org.koin.core.parameter.parametersOf data class DetailsScreen( diff --git a/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt b/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt index 240af1df..babfc127 100644 --- a/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt +++ b/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationActivity.kt @@ -4,13 +4,10 @@ import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.animation.ExperimentalAnimationApi import cafe.adriel.voyager.navigator.Navigator -import cafe.adriel.voyager.transitions.SlideTransition class BasicNavigationActivity : ComponentActivity() { - @OptIn(ExperimentalAnimationApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -21,11 +18,7 @@ class BasicNavigationActivity : ComponentActivity() { Log.d("Navigator", "Pop screen #${(currentScreen as BasicNavigationScreen).index}") true } - ) { navigator -> - SlideTransition( - navigator = navigator - ) - } + ) } } } diff --git a/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationScreen.kt b/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationScreen.kt index 58cf48b7..df5a8f3b 100644 --- a/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationScreen.kt +++ b/sample/src/main/java/cafe/adriel/voyager/sample/basicNavigation/BasicNavigationScreen.kt @@ -1,7 +1,6 @@ package cafe.adriel.voyager.sample.basicNavigation import android.util.Log -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -17,7 +16,6 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.LifecycleEffect import cafe.adriel.voyager.core.screen.Screen @@ -32,8 +30,6 @@ data class BasicNavigationScreen( override val key = uniqueScreenKey - private val colors = listOf(Color.LightGray, Color.Gray, Color.DarkGray) - @Composable override fun Content() { LifecycleEffect( @@ -49,7 +45,7 @@ data class BasicNavigationScreen( modifier = Modifier.run { if (wrapContent) wrapContentHeight() else fillMaxSize() - }.background(colors[index]) + } ) { Text( text = "Screen #$index", diff --git a/voyager-androidx/build.gradle b/voyager-androidx/build.gradle index 7d935416..0de8a2b4 100644 --- a/voyager-androidx/build.gradle +++ b/voyager-androidx/build.gradle @@ -13,6 +13,8 @@ android { dependencies { api projects.voyagerCore + implementation libs.lifecycle.runtime + implementation libs.lifecycle.savedState implementation libs.compose.viewModel implementation libs.compose.runtimeSaveable diff --git a/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/AndroidScreen.kt b/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/AndroidScreen.kt index c1604681..b46ba17e 100644 --- a/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/AndroidScreen.kt +++ b/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/AndroidScreen.kt @@ -1,6 +1,5 @@ package cafe.adriel.voyager.androidx -import androidx.lifecycle.ViewModelStoreOwner import cafe.adriel.voyager.core.hook.HookableScreen import cafe.adriel.voyager.core.hook.ScreenHookHandler import cafe.adriel.voyager.core.screen.Screen @@ -9,10 +8,10 @@ import cafe.adriel.voyager.core.screen.uniqueScreenKey public abstract class AndroidScreen : Screen, HookableScreen by ScreenHookHandler(), - ViewModelStoreOwner by ScreenViewModelStoreOwner() { + ScreenLifecycleOwner by ScreenLifecycleHolder() { init { - addHooks(viewModelScreenHooks) + addHooks(screenLifecycleHooks) } override val key: String = uniqueScreenKey diff --git a/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ScreenLifecycleOwner.kt b/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ScreenLifecycleOwner.kt new file mode 100644 index 00000000..a41f7e57 --- /dev/null +++ b/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ScreenLifecycleOwner.kt @@ -0,0 +1,41 @@ +package cafe.adriel.voyager.androidx + +import androidx.compose.ui.platform.LocalSavedStateRegistryOwner +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LifecycleRegistry +import androidx.lifecycle.ViewModelStore +import androidx.lifecycle.ViewModelStoreOwner +import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner +import androidx.savedstate.SavedStateRegistry +import androidx.savedstate.SavedStateRegistryController +import androidx.savedstate.SavedStateRegistryOwner +import cafe.adriel.voyager.core.hook.ScreenHook + +public val ScreenLifecycleOwner.screenLifecycleHooks: List + get() = listOf( + ScreenHook.OnProvide { LocalViewModelStoreOwner provides this }, + ScreenHook.OnProvide { LocalSavedStateRegistryOwner provides this }, + ScreenHook.OnDispose { viewModelStore.clear() } + ) + +public interface ScreenLifecycleOwner : LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner + +public class ScreenLifecycleHolder : ScreenLifecycleOwner { + + private val store = ViewModelStore() + + private val registry = LifecycleRegistry(this) + + private val controller = SavedStateRegistryController.create(this) + + init { + controller.performRestore(null) + } + + override fun getViewModelStore(): ViewModelStore = store + + override fun getLifecycle(): Lifecycle = registry + + override fun getSavedStateRegistry(): SavedStateRegistry = controller.savedStateRegistry +} diff --git a/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ViewModelStoreOwner.kt b/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ViewModelStoreOwner.kt deleted file mode 100644 index 9fce9318..00000000 --- a/voyager-androidx/src/main/java/cafe/adriel/voyager/androidx/ViewModelStoreOwner.kt +++ /dev/null @@ -1,19 +0,0 @@ -package cafe.adriel.voyager.androidx - -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner -import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner -import cafe.adriel.voyager.core.hook.ScreenHook - -public val ViewModelStoreOwner.viewModelScreenHooks: List - get() = listOf( - ScreenHook.OnProvide { LocalViewModelStoreOwner provides this }, - ScreenHook.OnDispose { viewModelStore.clear() } - ) - -public class ScreenViewModelStoreOwner : ViewModelStoreOwner { - - private val store = ViewModelStore() - - public override fun getViewModelStore(): ViewModelStore = store -}