androidkotlinandroid-jetpack-composejetpack-compose-navigation

Typesafe Navigation crashes with IllegalStateException: You must call setGraph() before calling getGraph()


This is my first Android app. Currently I'm working on the navigation part. Now the issue is, whenever I click the IconButton to navigate to the Add Notes Screen the app crashes with this exception:

java.lang.IllegalStateException: You must call setGraph() before calling getGraph()

In my MainActivity, I have this code:

val navController = rememberNavController()

NavHost(
    navController = navController,
    startDestination = Home,
) {
    composable<Home> {
        TopBar()
    }
    composable<AddNote> {
        // add Notes here
    }
}

And this are the navigation destinations I use:

@Serializable
object Home

@Serializable
object AddNote

This is a condensed version of my TopBar where I want to navigate to AddNote when the button is clicked:

@Composable
fun TopBar() {
    //navigate through screens
    val navController = rememberNavController()

    // IconButton to handle the add note action
    IconButton(onClick = { navController.navigate(AddNote) }) {
        Icon(
            imageVector = Icons.Rounded.Add,
            contentDescription = "Add Note",
        )
    }
}

Solution

  • Your app crashes because the navController you use to navigate to AddNote is not the same as the one you used to create your NavHost.

    Since the navController should never be passed around (it should be confined to the NavHost), you should instead pass a lambda to TopBar, like this:

    TopBar(
        navigateToAddNote = { navController.navigate(AddNote) }
    )
    

    The new parameter is a function that can be executed by TopBar. In the function the navController is used for the navigation, but TopBar never has access to the navController itself, it can only execute the function as a whole:

    @Composable
    fun TopBar(
        navigateToAddNote: () -> Unit,
    ) {
        // IconButton to handle the add note action
        IconButton(onClick = navigateToAddNote) {
            Icon(
                imageVector = Icons.Rounded.Add,
                contentDescription = "Add Note",
            )
        }
    }