6

Hi there I'm going through the guides for navigation on the developer Android site, and I followed the instructions to create a NavHostFragment:

<fragment
        android:id="@+id/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" />

However when that code is there the IDE suggests that I replace the NavHostFragment with FragmentContainerView.

What is the difference and when should they each be used rather than the other?

Thank you

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Wavecycle
  • 163
  • 1
  • 8
  • 1
    i'm not as it always showed me that hint to to change to fragmentcontainerview but it always crashed for me , fragmentcontainerview is like a framelayout i guess , i always continue with fragment – Taki Jul 14 '20 at 10:24
  • @takieddine if the crash happens in the `findNavController` check the answer below. – Gabriele Mariotti Jul 14 '20 at 12:16
  • 1
    As i read in the documentation , the FragmentContainview extends framelayout and it is useful when it comes to implementing transactions where as NavHostFramgent is necessary for navigation to work as it acts as controller all of the fragments and make them transactions , if something is wrong , please correct me – Taki Jul 14 '20 at 12:18

2 Answers2

11

The FragmentContainerView is a customized Layout designed specifically as the container for Fragments. The NavHostFragment is responsible for swapping destinations in the Navigation component.

You can use:

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:navGraph="@navigation/xxxxx"
    app:defaultNavHost="true"

    ..>

and:

val navController = findNavController(R.id.nav_host_fragment)

Or you can use:

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:navGraph="@navigation/xxxx"
    app:defaultNavHost="true"

    ..>

with:

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • ah so i guess the answer is to typecast that FragmentConainerView to NavhostFragment ? – Taki Jul 14 '20 at 12:19
  • @takieddine It is required if you are using the code in the OnCreate method (most of cases). The reason is [here](https://issuetracker.google.com/issues/142847973#comment2) – Gabriele Mariotti Jul 14 '20 at 12:25
2

If you explore the source code of FragmentContainerView, you will find it extends FrameLayout.

FragmentContainerView includes all features found in Framelayout, with some added features in Fragment Transition and etc..

Note: FragmentContainerView replaces <FrameLayout> and <fragment> not NavHostFragment.

To know more about FragmentContainerView, kindly check this article.

I hope this would help.

MustafaKhaled
  • 1,343
  • 9
  • 25