I'm getting an IllegalArgumentException with the message "ID does not reference a View inside this Activity" when calling findNavController(requireActivity(), R.id.mainNavHostFragment) inside the onViewCreated() method of a Fragment. The Fragment is created by a FragmentStateAdapter for a ViewPager, and the issue only occurs when returning to the application after a configuration change.

The NavHostFragment is located in the Fragment's Activity, and the ID is correctly referenced in the call to findNavController(requireActivity(), R.id.mainNavHostFragment). The issue only occurs after a configuration change.

Nav host in activity_main.xml:

 <fragment
                android:id="@+id/mainNavHostFragment"
                class="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginTop="?attr/actionBarSize"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_graph" />

Fragments onViewCreated:

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    navController = try {
        findNavController(view)
    } catch (e: IllegalStateException) {
        findNavController(requireActivity(), R.id.mainNavHostFragment)
    }
    keyboardManager.registerKeyboardConsumer(this)
}
1

There are 1 best solutions below

0
On

If you're getting the "IllegalArgumentException: ID does not reference a View inside this Activity exception" when calling findNavController(requireActivity(), R.id.mainNavHostFragment) inside onViewCreated(), it's possible that the NavHostFragment has not been fully initialised yet.

This happens when the Fragment is recreated due to a configuration change (such as system language change), because the Fragment's view hierarchy is destroyed and recreated. When the view hierarchy is recreated, it's possible that the NavHostFragment has not yet been recreated, so attempting to find its ID in the Activity's view hierarchy will result in the IllegalArgumentException being thrown.

Solution 1. Postpone call to onActivityCreated

To avoid this issue, you can delay the call to findNavController(requireActivity(), R.id.mainNavHostFragment) until the NavHostFragment has been fully initialized. One way to do this is to override the onActivityCreated() method in your Fragment, and call findNavController(requireActivity(), R.id.mainNavHostFragment) from there:

class MyFragment : Fragment() {

private lateinit var navController: NavController

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    navController = Navigation.findNavController(requireActivity(), R.id.mainNavHostFragment)
    // Use navController here
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    // Your other initialization code here
}
}

Solution 2. get navcontroller from host fragment

If a ViewPager child Fragment needs to obtain a reference to the NavController from the parent NavHostFragment, you can get it from the host Fragment.

As the parent NavHostFragment is part of a navigation graph, you can get a reference to the NavController by simply calling findNavController(view) in the parent Fragment's onViewCreated() method. You can then pass this reference to the child Fragments, or store it in a ViewModel that is shared between the parent and child Fragments.