Reputation: 458
I am using navigation component
and BottomNavigationView
, i am facing a problem, that is when i go to from fragment
1>2>5>4>3 and when i press back button i get fragment
1. I know this is the default behavior but i don't want this, i want to save them in backstack
so when i press back button it should go to fragment
4 not 1. I have been trying and searching but i couldn't find any solution. Can i put fragment
manually into backstack
in kotlin
?
My code:
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
.......................
.......................>
<androidx.appcompat.widget.Toolbar
................
................/>
<fragment
android:id="@+id/app_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:navGraph="@navigation/app_nav"
..............
............../>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/app_bottom_nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/white_grey_border_bottom"
app:menu="@menu/bottom_nav_menu"
app:labelVisibilityMode="unlabeled"
...........
.........../>
</androidx.constraintlayout.widget.ConstraintLayout>
app_nav.xml
<navigation
...........
...........
android:id="@+id/app_nav"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.example.instagram_clone.ui.HomeFragment"
android:label="HomeFragment"
tools:layout="@layout/fragment_home"/>
.............
.............
.............
.............
</navigation>
MainActivity.kt
class MainActivity : AppCompatActivity()
{
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
val bottomNavView = binding.appBottomNavView
val navController = findNavController(R.id.app_nav_host_fragment)
bottomNavView.setupWithNavController(navController)
}
}
Upvotes: 10
Views: 10337
Reputation: 835
I used the solution provided by @ianhanniballake
like using android:menuCategory="secondary
" in menu item but I encountered another problem that now android system started following the navigation track. So let suppose you navigate fragments like A -> B -> C -> D -> C -> B -> A.
Now press back button B is selected and displayed, again press back button C is displayed, again press back button D is displayed, again press back button C is displayed, again press back button B is displayed, again press back button A is displayed(start destination is reached and all fragments are pooped off the stack)
If you agains press the back button then app is closed.
So solution to this problem is handle back button navigation manually in the activity where your NavController is tied by using OnBackPressedDispatcher
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// If the current destination is not the start destination, pop the back stack
if (navController.currentBackStackEntry?.destination?.id != navController.graph.startDestinationId) {
navController.popBackStack()
} else {
// If the start destination is already reached, exit the app
isEnabled = false
finish()
}
}
})
Upvotes: 0
Reputation: 200110
As per the documentation on onNavDestinationSelected() (the method that setupWithNavController()
uses when selecting a MenuItem):
By default, the back stack will be popped back to the navigation graph's start destination. Menu items that have
android:menuCategory="secondary"
will not pop the back stack.
So just add android:menuCategory="secondary"
to each of the menu items used with your BottomNavigationView
.
Upvotes: 25