Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm trying to implement a multiple navigation controller with multiple back stack BottomNavigationView, as per the github examples. However, the example uses a different nav graph for each tab, which makes things easy. In my case I need to use the same nav graph for all of my tabs, but with different start destinations, than the "home destination" set in the nav graph.

So far I've managed to modify the NavigationExtensions file in order to achieve the single navgraph for all tabs, and I get multiple navControllers with their own back stacks, but I cannot figure out how to start a nav graph at a different destination.

I've tried using .navigate when getting the navcontroller, but since it's not yet attached, it does not work. Any ideas on how to achieve this? Thank you.

like image 243
Lucas P. Avatar asked Jun 26 '19 08:06

Lucas P.


People also ask

What is onSupportNavigateUp?

onSupportNavigateUp() This method is called whenever the user chooses to navigate Up within your application's activity hierarchy from the action bar. @Nullable ActionMode.

What is NavController in Android?

NavController manages app navigation within a NavHost . Apps will generally obtain a controller directly from a host, or by using one of the utility methods on the Navigation class rather than create a controller directly. Navigation flows and destinations are determined by the navigation graph owned by the controller.

What is NavHostFragment?

NavHostFragment provides an area within your layout for self-contained navigation to occur. NavHostFragment is intended to be used as the content area within a layout resource defining your app's chrome around it, e.g.: <androidx.drawerlayout.widget.DrawerLayout.


2 Answers

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);
    
like image 199
akubi Avatar answered Oct 16 '22 07:10

akubi


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)
like image 39
Morteza Rastgoo Avatar answered Oct 16 '22 09:10

Morteza Rastgoo