Android导航组件:是否以编程方式从与家不同的目的地开始?

时间:2019-06-26 08:24:14

标签: android android-architecture-navigation android-jetpack-navigation

我正在尝试根据github examples实现带有多个后退堆栈navigation controller的多个BottomNavigationView。但是,该示例为每个选项卡使用了不同的导航图,这使事情变得容易。在我的情况下,我需要对所有选项卡使用相同的导航图,但与导航图中设置的“家庭目标”不同,其起始目标是不同的。

到目前为止,我已经设法修改了NavigationExtensions文件以实现所有标签的单个navgraph,并且我获得了多个navControllers并带有自己的后置堆栈,但是我不知道如何在另一个目标位置启动导航图。

我在获取navcontroller时曾尝试使用.navigate,但是由于尚未附加,所以它不起作用。关于如何实现这一目标的任何想法?谢谢。

2 个答案:

答案 0 :(得分:2)

我写了两个扩展来完成这项工作。首先是用于更改当前节点中的目的地。第二个用于多次遍历嵌套图

_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
}

用法:

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

答案 1 :(得分:1)

我们有一个要求,其中显示的开始屏幕将取决于用户是否登录,我们要做的是以下事情:

  1. 在导航XML上删除app:startDestination
  2. 在主要活动的onCreate()上,我们创建一个NavGraph对象:

    NavController navController = Navigation.findNavController(this, R.id.your_nav_hostfragment);    
    NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.your_navigation_xml);
    
  3. 然后根据您的要求,可以使用setStartDestination在NavGraph上设置开始目标,然后将NavGraph应用于NavController:

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