2

Currently I have the following scenario: a user must sign in to use the app. This means I've used 2 nav_graphs, a main graph for everything and then a nested home graph for the views after you have signed in.

After signing in, a bottom navigation bar should appear to change tabs in the home graph.

I have the following home_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".ui.home.HomeFragment">

        <fragment
                android:id="@+id/home_nav_host_fragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                app:navGraph="@navigation/home_graph"
                app:defaultNavHost="true"/>

        <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottom_navigation"
                app:menu="@menu/navigation_items"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

And I want to be able to change tabs in the bottom navigation view, so I setup this logic in HomeFragement.kt using bottomNavigationView.setOnNavigationItemSelectedListener.

Unfortunetly, when I try to fetch the home_nav_host_fragment in home_fragment.xml I cannot because homeNavController = findNavController() in the fragment can only find the main_nav_host_fragment that's in the main activity.

I want findNavController() to return the home_nav_host_fragment instead but because this method only searches for parent NavControllers and not ones on the same level it cannot find the one I want.

Is there a better structure that will provide a solution to this issue? Thanks

2 Answers 2

2

This isn't the correct approach. Instead, you should listen for navigation events and hide the BottomNavigationView when you're on the login graph:

navController.addOnDestinationChangedListener { _, destination, _ ->
  if(destination.parent!!.id == R.id.login_graph) {
    toolbar.visibility = View.GONE
    bottomNavigationView.visibility = View.GONE
  } else {
    toolbar.visibility = View.VISIBLE
    bottomNavigationView.visibility = View.VISIBLE
  }
}

Then, you can use just a single graph, following the best practices for user login.

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

Comments

0

Better use popUpTo combined with popUpToInclusive to create a one-way navigation action - in order to use a single one graph, instead of two disconnected graphs. This only should be applied to the first 1-2 fragments in the graph, so that eg. the back button cannot navigate back to the splash-screen or to the login-screen, because these actions do not count towards "the expected behavior".

<fragment
    android:id="@+id/splashFragment"
    android:name="com.acme.fragment.SplashFragment"
    tools:layout="@layout/fragment_splash"
    android:label="fragment_splash">

    <action
        android:id="@+id/action_splashFragment_to_loginFragment"
        app:destination="@id/loginFragment"
        app:popUpTo="@id/splashFragment"
        app:popUpToInclusive="true"/>

</fragment>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.