Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple instances of same fragment: Android Navigation Component

I created a class to handle different back stacks for each tab inside my app, hence am using different nav controllers with a "currentcontroller" field to get the current one :

   private val navNewsController: NavController = obtainNavHostFragment(fragmentTag = "news", containerId = R.id.newsTabContainer).navController.apply {
        graph = navInflater.inflate(R.navigation.navigation_graph_main).apply {
            startDestination = startDestinations.getValue(R.id.tab_news)
        }
        addOnDestinationChangedListener { controller, destination, arguments ->
            onDestinationChangedListener?.onDestinationChanged(controller, destination, arguments)
        }
    }

    val navFormController: NavController = obtainNavHostFragment(fragmentTag = "form", containerId = R.id.formTabContainer).navController.apply {
        graph = navInflater.inflate(R.navigation.navigation_graph_main).apply {
            startDestination = startDestinations.getValue(R.id.tab_form)
        }
        addOnDestinationChangedListener { controller, destination, arguments ->
            onDestinationChangedListener?.onDestinationChanged(controller, destination, arguments)
        }
    }

  private fun obtainNavHostFragment(
            fragmentTag: String,
            containerId: Int
    ): NavHostFragment {
        val existingFragment = mainActivity.supportFragmentManager.findFragmentByTag(fragmentTag) as NavHostFragment?
        existingFragment?.let { return it }

        val navHostFragment = NavHostFragment.create(R.navigation.navigation_graph_main)
        mainActivity.supportFragmentManager.beginTransaction()
                .add(containerId, navHostFragment, fragmentTag)
                .commitNowAllowingStateLoss()
        return navHostFragment
    }

And when I switch tabs I just change the "currentController":

fun switchTab(tabId: Int, goToRoot: Boolean = false) {
    currentFragment()?.onPause()

    currentTabId = tabId

    when (tabId) {
        R.id.tab_news -> {
            currentController = navNewsController
            invisibleTabContainerExcept(newsTabContainer)
        }
        R.id.tab_form -> {
            currentController = navFormController
            invisibleTabContainerExcept(formTabContainer)
        }
....

So I have this FragmentA that opens from both news and form.

Whenever I open FragmentA from news and then FragmentA from form, FragmentA from news gets reloaded with the new arguments opened from form.

I tried using different actions inside the nav graph, I tried declaring the fragment twice with different ids and then different actions for the respective ids. I also tried making "newsAFragment" and "formAFragment" by just extending the original "AFragemnt" and still doesnt' work.

I also tried nav options:

NavOptions.Builder().setLaunchSingleTop(false).build()

How can I use multiple instances of the same fragment class inside a nav graph?

like image 534
Roudi Avatar asked Nov 01 '25 05:11

Roudi


1 Answers

Turns out the problem is with the ViewModel not the fragment itself.. It was using the same instance of the view model. Instead i know use a unique key for each instance from the viewmodelstore

like image 182
Roudi Avatar answered Nov 02 '25 18:11

Roudi