title: Using Navigation Component, what is the proper way to navigate up when using NavHostFragments nested within other NavHostFragments
body: <p>Please note that I am not talking about <a href="https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing#group" rel="noreferrer">Nested Navigation Graphs</a> here. I'm specifically talking about using <code>NavHostFragments</code> as subsections of other <code>NavHostFragments</code> and using the NavigationComponent to transition back and forth between the sub and parent fragments. That being said...</p>
  
  <p><strong>How do we properly use Navigation Component with NavHostFragments inside other NavHostFragments?</strong></p>
  
  <p>For example: Let's say I have a <code>MainActivity</code> with the following layout:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout
      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:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical"
      tools:context=".MainActivity"&gt;
      &lt;android.support.design.widget.AppBarLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"&gt;
          &lt;android.support.v7.widget.Toolbar
              android:id="@+id/toolbar"
              style="@style/Toolbar"/&gt;
      &lt;/android.support.design.widget.AppBarLayout&gt;
      &lt;fragment
          android:id="@+id/navHost"
          android:name="androidx.navigation.fragment.NavHostFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          app:defaultNavHost="true"
          app:navGraph="@navigation/nav_graph" /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Main Activity has a <code>NavHostFragment</code> with the id <code>navHost</code> that uses a navigation graph <code>nav_graph</code>, which looks like the following:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;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/fragmentA"&gt;
      &lt;fragment
          android:id="@+id/fragmentA"
          android:name="com.example.nestednavfragmentstest.FragmentA"
          android:label="FragmentA"
          tools:layout="@layout/fragment_a"&gt;
          &lt;action android:id="@+id/action_fragmentA_to_fragmentB" app:destination="@id/fragmentB"/&gt;
      &lt;/fragment&gt;
      &lt;fragment
          android:id="@+id/fragmentB"
          android:name="com.example.nestednavfragmentstest.FragmentB"
          android:label="FragmentB"
          tools:layout="@layout/fragment_b"/&gt;
  &lt;/navigation&gt;
  </code></pre>
  
  <p>Essentially, <code>navHost</code> can navigate from <code>FragmentA</code> to <code>FragmentB</code> (on say, a button click). But wait, there's more... </p>
  
  <p><strong>What if I would like <code>Fragment B</code> to contain it's own inner <code>NavHostFragment</code>?</strong> The xml might look something like this:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;android.support.constraint.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"&gt;
      &lt;TextView
          android:id="@+id/textView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Fragment B"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent"/&gt;
      &lt;fragment
          android:id="@+id/embeddedNavHostFragment"
          android:name="androidx.navigation.fragment.NavHostFragment"
          android:layout_width="match_parent"
          android:layout_height="0dp"
          android:layout_marginTop="50dp"
          app:defaultNavHost="true"
          app:layout_constraintTop_toBottomOf="@id/textView"
          app:layout_constraintBottom_toBottomOf="parent"
          app:navGraph="@navigation/inner_nav_graph"/&gt;
  &lt;/android.support.constraint.ConstraintLayout&gt;
  </code></pre>
  
  <p>As you can see, <code>FragmentB</code> has its own <code>NavHostFragment</code> called <code>embeddedNavHostFragment</code>, which has a navGraph that looks as follows:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;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/inner_nav_graph"
      app:startDestination="@id/innerFragmentB1"&gt;
      &lt;fragment
          android:id="@+id/innerFragmentB1"
          android:name="com.example.nestednavfragmentstest.InnerFragmentB1"
          android:label="InnerFragmentB1"
          tools:layout="@layout/inner_fragment_b1"&gt;
          &lt;action android:id="@+id/action_innerFragmentB1_to_innerFragmentB2" app:destination="@id/innerFragmentB2"/&gt;
      &lt;/fragment&gt;
      &lt;fragment
          android:id="@+id/innerFragmentB2"
          android:name="com.example.nestednavfragmentstest.InnerFragmentB2"
          android:label="InnerFragmentB2"
          tools:layout="@layout/inner_fragment_b2"/&gt;
  &lt;/navigation&gt;
  </code></pre>
  
  <p>As you can see, this inner <code>NavHostFragment</code> is used to navigate between two inner fragments <code>InnerFragmentB1</code> and <code>InnerFragmentB2</code>. Now for the main question...</p>
  
  <p><strong>What is the proper way override <code>onSupportNavigateUp()</code> in the <code>MainActivity</code>?</strong></p>
  
  <p>Originally, I did something like this:</p>
  
  <pre><code>override fun onSupportNavigateUp(): Boolean {
      return findNavController(R.id.navHost).navigateUp()
  }
  </code></pre>
  
  <p>But in certain cases, this would cause a crash due to back stack inconsistencies. For example:</p>
  
  <ol>
  <li><code>MainActivity</code> starts with Fragment <code>A</code> in <code>navHost</code>.</li>
  <li>Navigate via <code>action_fragmentA_to_fragmentB</code> to <code>B</code> (which starts with <code>B1</code> within <code>embeddedNavHost</code>)</li>
  <li>Navigate via <code>action_innerFragmentB1_to_innerFragmentB2</code> from <code>B1</code> to <code>B2</code> (occurs on <code>embeddedNavHost</code>)</li>
  <li>Press Up (<code>embeddedNavHost</code> returns from <code>B2</code> to <code>B1</code> [desired outcome])</li>
  <li>Press Up (<code>navHost</code> returns from <code>B</code> to <code>A</code> [desired outcome])</li>
  <li>Navigate again via <code>action_fragmentA_to_fragmentB</code> to <code>B</code></li>
  <li><code>IllegalArgumentException: navigation destination id/action_fragmentA_to_fragmentB</code> [not desired outcome]</li>
  </ol>
  
  <p>So in the end, I ended up doing:</p>
  
  <pre><code>override fun onSupportNavigateUp(): Boolean {
      val hostedFragment = navHost?.childFragmentManager?.primaryNavigationFragment
      return when(hostedFragment){
          is FragmentB -&gt; {
              if(hostedFragment.isInnerFragmentB2Showing()){
                  findNavController(R.id.embeddedNavHostFragment).navigateUp()
              } else {
                  findNavController(R.id.navHost).navigateUp()
              }
          }
          is FragmentA -&gt; {
              findNavController(R.id.navHost).navigateUp()
          }
          else -&gt; false
      }
  }
  </code></pre>
  
  <p>This ended up working. There was no crash. But, I'm just curious as to <strong>if there's a more proper/automated way</strong> handle the up navigation of embedded <code>NavHostFragments</code>. This current way feels more like a workaround than a proper solution. Are there any other <strong>alternatives</strong> to how to get this to work?</p>
  
  <p>Also, I'm curious of people's <strong>opinions of <code>NavHostFragments</code> being embedded</strong> within each other. Is it an appropriate use? Figuring out how to handle the back button accordingly was not an easy or straight forward solution as there was no documentation on embedding <code>NavHostFragments</code> inside one another and navigating back &amp; forth between parent and sub fragments. So, I'm wondering if the reason why there is no documentation is because maybe it's an improper (or unexpected) use of NavigationComponent and therefore <strong>not</strong> recommended.</p>
  
  <p>If you'd like to take a look at my sample project, please go <a href="https://github.com/jeffreyfhow/NestedNavFragmentsTest" rel="noreferrer">here</a></p>