How to change start destination of a navigation graph programmatically [Jetpack]

前端 未结 7 1767
醉酒成梦
醉酒成梦 2020-12-08 00:30

Basically, I have the following navigation graph:

I want to change my starting point in navigation graph to fragment 2 right after reaching it

相关标签:
7条回答
  • 2020-12-08 01:01

    I found a solution for this, but it's ugly. I guess this it to be expected with an alpha library, but I hope Google looks into simplifying/fixing this as this is a pretty popular navigation pattern.

    Alexey's solution did not work for me. My problem was that I have up arrows showing on my Actionbar by using:

    NavigationUI.setupActionBarWithNavController(this, navController)

    If I did as Alexey suggests above, my new start fragment still had a arrow pointing to my initial start fragment. If I pressed that up arrow my app would sort-of restart, transitioning to itself (the new start fragment)

    Here is the code needed to get to what I wanted which was:

    • Fragment #1 is where my application initially starts
    • I can do an Auth check in Fragment #1 and then programmatically change the start to fragment #2.
    • Once in Fragment #2 there is no up arrow and pressing the back button does not take you to Fragment #1.

    Here is the code that accomplishes this. In my Activity's onCreate:

    // Setup the toolbar
    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayHomeAsUpEnabled(false)
    
    // Configure the navigation
    val navHost = nav_host_fragment as NavHostFragment
    graph = navHost.navController
            .navInflater.inflate(R.navigation.nav_graph)
    graph.startDestination = R.id.welcomeFragment
    
    // This seems to be a magical command. Not sure why it's needed :(
    navHost.navController.graph = graph
    
    NavigationUI.setupActionBarWithNavController(this, navHost.navController)
    

    and also:

    fun makeHomeStart(){
        graph.startDestination = R.id.homeFragment
    }
    

    Then in Fragment #1's onActivityCreated, per Alexey's suggestion:

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        ...
    
        // Check for user authentication
        if(sharedViewModel.isUserAuthenticated()) {
    
            (activity as MainActivity).makeHomeStart() //<---- THIS is the key
            val navOptions = NavOptions.Builder()
                    .setPopUpTo(R.id.welcomeFragment, true)
                    .build()
            navController.navigate(R.id.action_welcomeFragment_to_homeFragment,null,navOptions)
    
        } else {
            navController.navigate(R.id.action_welcomeFragment_to_loginFragment)
        }
    }
    

    The key code is: (activity as MainActivity).makeHomeStart() which just runs a method in the activity that changes the graphs startDestination. I could clean this up and turn it into an interface, but I'll wait for Google and hope they improve this whole process. The method 'setPopUpTo' seems poorly named to me and it's not intuitive that your naming the fragment that is getting cut out of the graph. It's also strange to me that they're making these changes in navOptions. I would think navOptions would only relate to the navigation action they're connected to.

    And I don't even know what navHost.navController.graph = graph does, but without it the up arrows return. :(

    I'm using Navigation 1.0.0-alpha06.

    0 讨论(0)
提交回复
热议问题