0

I need to set a Fragment to nav graph programmatically. I have tried the below approach to set it in my activity but getting the below error "Fatal Exception: java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager. " Can anyone please help pointing to what I am doing wrong.

<androidx.fragment.app.FragmentContainerView
        android:id="@+id/main_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />
 
  <navigation xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/nav_graph"
              app:startDestination="@id/homeFragment">
  
      <fragment android:id="@+id/profileFragment" />
  
      <fragment android:id="@+id/homeFragment"
                android:name="HomeFragment"
                android:label="fragment_home"
                tools:layout="@layout/fragment_home"/>
  </navigation>
Fragment profileFragment = ProfileFragment()
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.main_nav_host_fragment);
NavDestination profileNode = navHostFragment.getNavController().getGraph().findNode(R.id.profileFragment);
((FragmentNavigator.Destination) startDestNode).setClassName(profileFragment.getClass().getName());

Error Fatal Exception: java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.

Fragment ProfileFragment{32a2ed0 (d41fc341-baf2-4266-948a-866fba7e57b5) id=0x7f09028b profile_fragment} is already attached to a FragmentManager. at androidx.fragment.app.BackStackRecord.remove(BackStackRecord.java:316)

marsuser
  • 125
  • 9
  • You should **never** be using `app:navGraph="@navigation/nav_graph"` if you're programmatically changing the graph as per [the documentation](https://developer.android.com/guide/navigation/navigation-programmatic#modify_inflated). You also shouldn't be doing any `FragmentTransaction` at all when using Navigation. Can you explain what exactly you're doing? – ianhanniballake Jun 24 '21 at 00:12
  • Thanks for responding. I want to set ProfileFragment destination programmatically, So just added the ProfileFragment as a placeholder in navigation xml file. I also have bottom navigation view below this FragmentContainerView. When user clicks on Profile tab, it should show ProfileFragment. Trying to follow the placeholder approach in this doc https://developer.android.com/guide/navigation/navigation-getting-started but not able to figure out how to add that fragment programatically. – marsuser Jun 24 '21 at 02:39
  • Placeholders are for quickly building out your graph in the tool, you need to replace them all with actual fragments in your navigation graph before running your app. Why are you doing anything programmatically at all? – ianhanniballake Jun 24 '21 at 02:45
  • Because I don' have access to ProfileFragment in compile time. I only get this during runtime as it is from different module. Is there any way that I can set this ProfileFragment to the graph? I thought setting class name at runtime will set the fragment in nav graph. – marsuser Jun 24 '21 at 02:50
  • You mean in a different module as in a library module? Or a different module as in a dynamic feature module? Navigation has [specific support for dynamic feature modules](https://developer.android.com/guide/navigation/navigation-dynamic), which would be the only time you don't have access to the class at compile time. – ianhanniballake Jun 24 '21 at 03:44
  • It's in a different module as in a library module. I think this dynamic feature modules is what I am looking for but it still doesn't show programmatic way of replacing the fragment. I can't set is in xml as there are some other operations that get performed on that fragment before adding to container. – marsuser Jun 24 '21 at 20:57

0 Answers0