10

in the fragment which i made it host in the tag fragment in activity when i use navController = Navigation.findNAvController(view) the app crashes by the error: View does not have a navController set.

this is 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/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="studio.apptick.mouj.view.fragments.MainFragment"
        tools:layout="@layout/fragment_main"
        android:label="fragment_main" >
        <action
            android:id="@+id/action_mainFragment_to_playlistActivityFragment"
            app:destination="@id/playlistActivityFragment" />
        <action
            android:id="@+id/action_mainFragment_to_searchActivity"
            app:destination="@id/searchActivity" />
    </fragment>
    <activity
        android:id="@+id/searchActivity"
        android:name="studio.apptick.mouj.view.activity.SearchActivity"
        android:label="activity_search"
        tools:layout="@layout/activity_search" />
</navigation>

this is fragment tag in activity:

        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/view_player"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph">
    </fragment>
james rm
  • 101
  • 1
  • 1
  • 4

9 Answers9

9

If you want navController in activity you can find it via

navController = Navigation.findNavController(Activity, R.id.nav_host_fragment)

or in a fragment

navController = NavHostFragment.findNavController(Fragment)

or

navController = Navigation.findNavController(View)
Asad Mahmood
  • 532
  • 1
  • 5
  • 15
9

I was facing the same issue, until I realized that we have to setup navControol onPostCreate function like this

@Override
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
    super.onPostCreate(savedInstanceState, persistentState);

    BottomNavigationView navigationView = findViewById(R.id.nav_view);


    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_home, R.id.navigation_memories, R.id.navigation_account)
            .build();
    NavController navController = Navigation.findNavController(this, R.id.main_fragment);
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navigationView, navController);
}
Akshay Sahai
  • 2,121
  • 1
  • 17
  • 20
  • how can you handle navController and back stack. Example you have selected 2nd Number navigation it have inside 5 fragment. you are on 4th fragment and you have exit current fragment and get back to 2nd number navigation 1st or 2nd fragment???? – Dens Oct 27 '20 at 02:12
6

I got today alike error

ava.lang.IllegalStateException: Activity com.example.roomtutorial.MainActivity@2a8d7bb does not have a NavController set on 2131231116

I get this error pointing on setupActionBarWithNavController(findNavController(R.id.mainFragment))

So the problem was in XML

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"

etc..... I delt with a problem by changing <androidx.fragment.app.FragmentContainerView to <fragment

Someone who designs the option really messed it up.

Valery Lavrov
  • 91
  • 1
  • 3
  • 1
    This was the cause of my crash as well. What's the general fix for this? I actually want to use `FragmentContainerView`. – Taslim Oseni Oct 27 '21 at 14:33
2

You can use the Kotlin Extension Function to navigate to the destination.

findNavController().navigate(R.id.action_homeFragment_to_destinationFragment)

Also, make sure you use to replace the fragment tag with FragmentContainerView as recommended by android.

<androidx.fragment.app.FragmentContainerView
   android:id="@+id/my_nav_host_fragment"
   android:layout_width="match_parent"
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:defaultNavHost="true"
   app:navGraph="@navigation/nav_graph"
   android:layout_height="match_parent"/>
Chintan Parmar
  • 2,375
  • 2
  • 12
  • 22
1

Initiate the navController after view created in case of fragment

 //    ....
lateinit var navController: NavController
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    navController = Navigation.findNavController(view)
    //...
}
Zulqarnain
  • 611
  • 7
  • 18
1

I use to this solution in my projects.

navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController

navController.addOnDestinationChangedListener { controller, destination, arguments ->
                when(destination.id){
                    R.id.genre->{ materialToolbar.title = getString(R.string.app_name) }
                    R.id.search->{ materialToolbar.title = getString(R.string.search) }
                    R.id.favorites->{ materialToolbar.title = getString(R.string.favorites) }

                }
            }
fevziomurtekin
  • 192
  • 1
  • 3
  • 10
0

You can simply use post method on your nav host fragment view:

    nav_host_fragment.post {
        findNavController(R.id.nav_host_fragment).addOnDestinationChangedListener { _, des, _ ->
            when(des.id){
                //your conditions here
            }
        }
    }
amir_a14
  • 1,478
  • 10
  • 15
0

If you get navController via

NavController navController = Navigation.findNavController(Activity, R.id.nav_host_fragment);

Solution 1

Get navController via the following method

NavHostFragment navHostFragment =
                (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

With layout:

<androidx.fragment.app.FragmentContainerView
   android:id="@+id/nav_host_fragment"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:name="androidx.navigation.fragment.NavHostFragment"
   app:defaultNavHost="true"
   app:navGraph="@navigation/nav_graph"/>

It is fully compliant with Documentation

Solution 2

Simply changing <androidx.fragment.app.FragmentContainerView to <fragment

It works for me, but I don't find any DOC associate to it.

Hope that helps!

etoyz
  • 32
  • 6
0

I had the same issue and found that problem was in my activity class which was not configured as it done when create activity with fragments with help of the Basic Activity. Try to create Basic activity and see if created activity class is similar to your initial class with problem

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Vikram Parimi Sep 07 '22 at 12:09