Hey recently I had discovered this weird behaviour of bottom navigation when I setup with NavController.
Problem
Only the start destination in navigation graph for bottom nav, saves its state. While others don't.[That means onDestroy is never called for starting destination only]. Now the issues with this is ViewModel associated with starting destination nav graph never gets cleared.
Behaviour I am looking for
How to make starting destination lifecycle behave as all the other destinations, so on destination change the viewModel will be cleared?
Code snippet :
<?xml version="1.0" encoding="utf-8"?>
<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_main"
app:startDestination="@+id/nav_main_home">
<include
android:id="@+id/home_fragment_graph"
app:graph = "@navigation/nav_main_home"/>
<include
android:id="@+id/profile_fragment_graph"
app:graph = "@navigation/nav_main_profile"/>
<include
android:id="@+id/message_fragment_graph"
app:graph = "@navigation/nav_main_message"/>
</navigation>
nav_main_home -nav_graph- for HomeFragment
nav_main_profile -nav_graph- for ProfileFragment
nav_main_message -nav_graph- for MessageFragment
Now when I switch from HomeFragment to ProfileFragment or MessageFragment the onDestroy for HomeFragment is not called. But when I switch from ProfileFragment or MessageFragment the onDestroy is called for both of them.
Fragments (and by extension Navigation) save the state of fragments on the back stack. As per the Principles of Navigation, the start destination of your graph should always be on the back stack and that's why you go back to the start destination when you hit back from one of the other bottom nav items and why it retains its state. You should never be purposefully throwing away the user's state.
The reason other bottom nav items don't keep their state is that once you switch off of them by hitting another bottom nav item, they are no longer on the back stack and hence Fragments destroy and throw away any state associated with those Fragments.
There's an existing issue for supporting multiple back stacks which would cause every bottom nav item to save its state and restore it when you go back to it. As that issue is not yet fixed, there is a NavigationAdvancedSample that offers a temporary workaround to get that behavior.