androidkotlinandroid-jetpack-compose

Type safe navigation: Starting destination with argument


At one point in my app I want to navigate to a nested graph that's starting destination requires an ID from the previous screen, but I get an error:

kotlinx.serialization.SerializationException: Serializer for class 'Companion' is not found.  
                                                                                                Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.

The Graph:

@Serializable
data object MainScreen {

    @Serializable
    data class MainScreenFirstScreen(val id: Int)
}

The Navigation:

            onNavigateToNextScreen = { id ->
                navHostController.navigate(
                    route = OwnerGraph.MainScreen.MainScreenFirstScreen(
                        id = id
                    )
                )

The NavGraph

fun NavGraphBuilder.mainScreenOwnerNavGraph(
    navHostController: NavHostController,
) {
    navigation<OwnerGraph.MainScreen>(
        startDestination = OwnerGraph.MainScreen.MainScreenFirstScreen
    ) {
        composable<OwnerGraph.MainScreen.MainScreenFirstScreen> { navBackStackEntry ->
            Text("Main Screen")
        }
    }
}

Solution

  • You have to pass either argument or default value in route. If you just want to ignore passing arguments in OwnerGraph.MainScreen.MainScreenFirstScreen modify your routes like below,

    Add default value,

    @Serializable
    data object MainScreen {
    
        @Serializable
        data class MainScreenFirstScreen(val id: Int= -1) // Added default value
    }
    

    The in your navgraph builder add constructor to ignore passing arguments startDestination = OwnerGraph.MainScreen.MainScreenFirstScreen()

    fun NavGraphBuilder.mainScreenOwnerNavGraph(
        navHostController: NavHostController,
    ) {
        navigation<OwnerGraph.MainScreen>(
            startDestination = OwnerGraph.MainScreen.MainScreenFirstScreen()
        ) {
            composable<OwnerGraph.MainScreen.MainScreenFirstScreen> { navBackStackEntry ->
                Text("Main Screen")
            }
        }
    }