olshevski / compose-navigation-reimagined

🌈 Type-safe navigation library for Jetpack Compose
https://olshevski.github.io/compose-navigation-reimagined/
MIT License
541 stars 18 forks source link

Preserving State #38

Open rpuxa-copilot opened 1 month ago

rpuxa-copilot commented 1 month ago

How can I achieve the same state preservation in this library as I had with a stack of activities? When I open a new activity on top of another, the state of the underlying activity is preserved, including all Views and ViewModels. However, when trying to replicate this behavior with AnimatedHost in Jetpack Compose, the state of the previous screen is lost. This includes the state managed by remember, AndroidView, and ViewModel. What can I do to ensure that the state of the previous screen is retained when navigating between screens using AnimatedHost?

olshevski commented 1 month ago

@rpuxa-copilot For saving a state of a composable function you should use 'rememberSaveable' https://developer.android.com/develop/ui/compose/state#restore-ui-state

For saving a state of a ViewModel use 'SavedStateHandle' https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-savedstate

The library fully supports this functionality and doesn't change the already existing API in any way.

rpuxa-copilot commented 1 month ago

I think you completely misunderstood my question. I don't need to save the state during activity or process death. I need to save state when I go to another screen and back. Here is the simplest example I can provide.

    @Composable
    fun Test() {
        Column {
            val navController = rememberNavController(startDestination = 1)

            Text(text = "Next", modifier = Modifier.clickable {
                navController.navigate(navController.backstack.entries.last().destination + 1)
            })

            Text(text = "Prev", modifier = Modifier.clickable {
                navController.pop()
            })

            NavHost(navController) { destination ->
                AndroidView(factory = {
                    WebView(it).apply {
                        loadUrl("www.example.com/$destination")
                    }
                })
            }
        }
    }

If I click Next and than Prev, the first WebView gets reloaded. This happens because when I go from screen 1 to screen 2, the first WebView gets discarded. This also happens to remember functions and ViewModels.

If I used Fragments or Activities, I wouldn't get this problem

rpuxa-copilot commented 1 month ago

I am sorry, you where right about rememberSaveable. But, I think, I have to do something about AndroidView by myself (implement some kind of cache logic with rememberSaveable). Thank you for your answer!