adrielcafe / voyager

🛸 A pragmatic navigation library for Jetpack Compose
https://voyager.adriel.cafe
MIT License
2.38k stars 115 forks source link

Navigator not working in Kotlin multiplatform after screen orientation change #319

Open Sandeep03edu opened 5 months ago

Sandeep03edu commented 5 months ago

I am using voyagerVersion = "1.1.0-alpha02" in my Kotlin multiplatform application and using the below dependencies in commonMain

// ScreenModel
implementation("cafe.adriel.voyager:voyager-screenmodel:$voyagerVersion")
// Navigator
implementation("cafe.adriel.voyager:voyager-navigator:$voyagerVersion")
// BottomSheetNavigator
implementation("cafe.adriel.voyager:voyager-bottom-sheet-navigator:$voyagerVersion")
// TabNavigator
implementation("cafe.adriel.voyager:voyager-tab-navigator:$voyagerVersion")
// Transitions
implementation("cafe.adriel.voyager:voyager-transitions:$voyagerVersion")

I have initialized the Navigator in App.kt as below

Navigator(
        rememberSaveable { AppHomeLayout(darkTheme, dynamicColor, appModule) }
    )

Inside the 'AppHomeLayout' composable function, I am initializing the voyager navigator as below val navigator = LocalNavigator.currentOrThrow

I am navigating to other composable class like below

navigator.push(
      SecondScreenLayoutClass(
            appModule
      )
)
data class SecondScreenLayoutClass(
    val appModule: AppModule,
) : Screen{
@Composable
    override fun Content() {
    // Content
    }
}

The app functions correctly as long as the screen orientation remains unchanged. However, when I alter the orientation or configuration, the navigator ceases to work. Am I doing anything wrong?

rasskazovaleksey commented 4 months ago

Greetings,

@Sandeep03edu I'm not 100% sure but it seems you are trying to inject Navigator to appModule. On screen rotation new instance of Navigator is created and it seems you saved in DI old instance. You can verify this theory by simply Log.d("TAG", navigator.toString()) instance of Navigator val navigator = LocalNavigator.currentOrThrow most likely you are triggering old instance.

DevSrSouza commented 2 months ago

What is a AppModule. Voyager Screens requires to be serializable, this is how State Retauration works out of the box on Voyager, if the AppModule model is not Java Serializable it will crash. Can you share more examples? Maybe try to clone voyager and reproduce on Voyager Multiplatform samples and share the code?

DevSrSouza commented 2 months ago

There are documentation explaining state restauration on KMP projects: https://voyager.adriel.cafe/state-restoration#multiplatform-state-restoration

davehorner commented 1 month ago

I am also running into an issue where I am calling show and it does not show. I can reliably open and close the bottom sheet fine when in portrait/landscape. If I have a bottom sheet open and rotate the screen, the bottom sheet stops displaying and future calls to show() do not work.

My code is basically the same as the sample. It's wrapped in a BottomSheetNavigator. BottomSheetNavigator { Navigator(BackScreen()) } val bottomSheetNavigator = LocalBottomSheetNavigator.current onClick = { bottomSheetNavigator.show(BasicNavigationScreen(index = 0, wrapContent = true)) }

using val navigator = LocalNavigator.currentOrThrow as suggested can't happen in the onclick "@Composable invocations can only happen from the context of a @Composable function"

I'm not sure what to do to get a fresher reference.

davehorner commented 4 weeks ago

In my case, I found that there was something very wrong with the following :

    val colors by mutableStateOf(
        if (isSystemInDarkTheme()) darkColors else lightColors
    )

(studio redlined it and said Creating a state object during composition without using remember)

    val isDarkTheme = isSystemInDarkTheme()
    val colors by remember { mutableStateOf(
        if (isDarkTheme) darkColors else lightColors
    )}

the bottom sheet now survives rotation. Make sure to look at serialization and state... this one took me some time to uncover. hope this helps someone else.