Reputation: 6944
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
Upvotes: 2
Views: 1164
Reputation: 76579
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>
Upvotes: 0
Reputation: 199805
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.
Upvotes: 2