6

This is a simple example of a navigation setup that I can't get to work with the Navigation Component library, after researching for some time.

Let's say I have the following screen: enter image description here

The sticky fragment at the top and the fragment at the bottom are in their own navigation graphs, here is the main_activity.xml:

<androidx.constraintlayout.widget.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">

    <fragment
        android:id="@+id/nav_sticky_top"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/navigation_graph_sticky_top" />

    <fragment
        android:id="@+id/navigation_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/nav_sticky_top"
        app:navGraph="@navigation/navigation_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

When I press "navigate to sibling fragment" it navigates to the sibling fragment inside the bottom navigation graph, which is correct, the result:

enter image description here

This is the navigation_graph.xml:

<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/navigation_graph.xml"
    app:startDestination="@id/blankFragment1">

    <fragment
        android:id="@+id/blankFragment1"
        android:name="com.example.myapplication.BlankFragment1"
        android:label="fragment_blank_fragment1"
        tools:layout="@layout/fragment_blank_fragment1">

        <action
            android:id="@+id/action_blankFragment1_to_siblingFragment"
            app:destination="@id/siblingFragment" />

    </fragment>

    <fragment
        android:id="@+id/siblingFragment"
        android:name="com.example.myapplication.SiblingFragment"
        tools:layout="@layout/fragment_sibling_fragment" />

</navigation>

Now I would like to implement the "Navigate to fullscreen fragment" button, which should navigate to a fullscreen fragment which is in a separate, third navigation graph and should be above the sticky fragment navigation graph and the navigation graph below that. How can this be properly achieved? By that I mean without hacks like setting the visibility of the top navigation graph fragment to GONE and navigating in the bottom navigation graph to the fullscreen fragment.

1 Answer 1

5

UPDATE: I don't recommend this approach any more. For small apps it may work for you, but I ran into complications when trying to pass data between different navigation graphs hosted inside different NavHostFragments. I think the easiest route is the "hack" of hiding fragments in your top level layout to allow a full screen view. You can add an addOnDestinationChangedListener to listen for destinations that you want full screen, and simply hide the fragment required.

ORIGINAL ANSWER: I do it like this in my app and it works well. You should wrap all your current fragments in a parent fragment with a main_nav_graph.xml. For example:

<androidx.constraintlayout.widget.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">

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

</androidx.constraintlayout.widget.ConstraintLayout>

Then your navigation for full screen fragments will look like this:

<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/main_nav_graph.xml"
    app:startDestination="@id/main_fullscreen">

    <fragment
        android:id="@+id/main_fullscreen"
        android:name="com.example.myapplication.MainFullscreen" >

        <action
            android:id="@+id/action_main_fullscreen_to_fullscreen2"
            app:destination="@id/fullscreen2" />

    </fragment>

    <fragment
        android:id="@+id/fullscreen2"
        android:name="com.example.myapplication.Fullscreen2" />
</navigation>

Where the MainFullscreen has a layout like your ConstraintLayout you provided. Just make sure you add app:defaultNavHost="true" to all your child NavHostFragments.

Then when I want to navigate from your blankFragment1 to fullscreen2, I call this:

Navigation.findNavController(activity!!, R.id.main_host_fragment).navigate(R.id.action_main_fullscreen_to_fullscreen2)

Granted, there's not much point to having navigation graphs if they are not actually connected except via being in the same activity, but I just like the pretty picture of the app the graphs give you in the navigation editor :)

Sign up to request clarification or add additional context in comments.

6 Comments

Interesting, I will have to try this.
Just to warn you. I've found a major problem with this. The hardware back button doesn't navigate back within the nested nav host :(. Waiting for google's response
Acutally that wasn't a bug. You just need to add app:defaultNavHost="true" to both NavHostFragments
Three months later I came around to testing this and it works well, thanks. I'm releasing my app next week though so I think it won't make it into this release =)
I no longer recommend this approach. I ran into problems passing data around my app due to screens existing in different navigation graphs. If possible I recommend having only one NavHostFragment in your app. To achieve this I recommend the "hack" of hiding the fragment to achieve a full screen view. With addNavigationListener, I think this is reasonably clean, with less drawbacks.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.