Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Navigation Component with Bottom Navigation doesn't destroy startDestination Fragment

I've set up bottom navigation with nav graph, in the most basic way -

NavigationUI.setupWithNavController(bottomNavigationView, navHostFragment.navController)

the fragment that's declared as startDestination is never destroyed when navigating from it (only paused) while all other fragments are destroyed when navigating away.

(I need it to be destroyed so that in the viewModel associated with it onCleared() will be called).

Any idea why? or How to change this behavior?

navigation:

<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"
app:startDestination="@id/drawingFragment">

<fragment
    android:id="@+id/controllerFragment"
    android:name="com.example.android.myApp.ControllerFragment"
    android:label="fragment_controller"
    tools:layout="@layout/fragment_controller" >
    <action
        android:id="@+id/action_controllerFragment_to_drawingFragment"
        app:destination="@id/drawingFragment" />
</fragment>
<fragment
    android:id="@+id/drawingFragment"
    android:name="com.example.android.myApp.DrawingFragment"
    android:label="fragment_drawing"
    tools:layout="@layout/fragment_drawing" >
    <action
        android:id="@+id/action_drawingFragment_to_clippingFragment"
        app:destination="@id/clippingFragment"
        app:launchSingleTop="true"
        app:popUpTo="@+id/drawingFragment"
        app:popUpToInclusive="true" />
</fragment>
<fragment
    android:id="@+id/clippingFragment"
    android:name="com.example.android.myApp.ClippingFragment"
    android:label="fragment_clipping"
    tools:layout="@layout/fragment_clipping" />

MainActivity:

class MainActivity : AppCompatActivity() {

private lateinit var navHostFragment: NavHostFragment
private lateinit var bottomNavigationView: BottomNavigationView


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setUpNavigation()
}

fun setUpNavigation(){
    bottomNavigationView = findViewById(R.id.bttm_nav)
     navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

    NavigationUI.setupWithNavController(bottomNavigationView, navHostFragment.navController)}

activity_main/xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

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

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bttm_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:itemTextAppearanceActive="@style/bottomNaActive"
        app:itemTextAppearanceInactive="@style/bottomNavInactive"
        app:layout_constraintBottom_toBottomOf="@+id/nav_host_fragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_menu_nav" />
</androidx.constraintlayout.widget.ConstraintLayout>
like image 263
LironIz Avatar asked Nov 06 '22 10:11

LironIz


1 Answers

this is actually no answer rather than a comment on @isrzanza's answer (sorry, not enough reputation).

I assumed in case of BottomNavigationView there is no up or down. For me each fragment which I can navigate from here a more like neighbors respectively equal important so I thought not only the ViewModels of these were cleared rather I asssumed that the fragment itself would be destroyed via onDestroy when navigating away.

I don't know why specially the start fragment should stay in memory and the others don't, because they are equal important, didn't they?


EDIT:

I also want to mention I noticed if I navigate to the startDestination-fragment again a new fragment of same type is created (onCreate will be executed again) and the old one will be destroyed (onDestroy will be executed). For me this is a other waste in resources. To keep the fragment for this situation in memory and re-create it afterwards anyway makes no sense to me. Hope I misunderstood something here :)

like image 62
chrgue Avatar answered Nov 11 '22 11:11

chrgue