Android Navigation Component: Start at a different destination than home, programmatically? Android Navigation Component: Start at a different destination than home, programmatically? android android

Android Navigation Component: Start at a different destination than home, programmatically?


We had a requirement wherein the displayed start screen would depend if the user has logged on, what we did was the following:

  1. Remove app:startDestination on the navigation XML if it exists
  2. On your main activity's XML, remove the following fields inside the <fragment> tag: app:defaultNavHost="true" and app:navGraph
  3. On our main Activity's onCreate(), we create a NavGraph object :

    NavController navController = Navigation.findNavController(this, R.id.your_nav_hostfragment);    NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.your_navigation_xml);
  4. Then depending on your requirement, you can set the start destination on the NavGraph using setStartDestination, then apply the NavGraph to the NavController:

        if (condition) {        navGraph.setStartDestination(R.id.screen1);    } else {        navGraph.setStartDestination(R.id.screen2);    }    navController.setGraph(navGraph);


I wrote two extensions to do the job. First is to be used to change destination in the current node. The second is to be used to traverse multiple times into nested graphs

_main_graph | |_nested_graph_1   |   |_nested_graph_2       |     |_nested_graph_3       |       |_nested_graph_4         |         |_change this destination!!!!  
fun NavController.changeNodeDestination(nodeId: Int, destinationId: Int): NavController {    val graph = graph.findNode(nodeId) as NavGraph    graph.startDestination = destinationId    return this}fun NavController.changeNodeDestination(vararg nodeIds: Int, destinationId: Int): NavController {    var currentNode = graph    nodeIds.forEachIndexed { index, i ->        currentNode = currentNode.findNode(nodeIds[index]) as NavGraph    }    currentNode.startDestination = destinationId    return this}

Usage:

        findNavController().changeNodeDestination(            R.id.navigation_login,            R.id.nav_change_password,                  // GO two levels inside nested graphs            destinationId = startDestination        ).navigate(navID, bundle)