带有底部导航的 Android 导航组件不会破坏 startDestination 片段

Lir*_*nIz 5 android android-architecture-navigation

我已经以nav graph最基本的方式设置了底部导航-

NavigationUI.setupWithNavController(bottomNavigationView, navHostFragment.navController)
Run Code Online (Sandbox Code Playgroud)

被声明为的片段startDestination在从它导航时永远不会被销毁(仅暂停),而所有其他片段在导航离开时都被销毁。

(我需要销毁它,以便在与其关联的 viewModel 中onCleared()被调用)。

知道为什么吗?或如何改变这种行为?

导航:

<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" />
Run Code Online (Sandbox Code Playgroud)

主要活动:

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)}
Run Code Online (Sandbox Code Playgroud)

活动_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>
Run Code Online (Sandbox Code Playgroud)

isr*_*nza 0

您所描述的是导航组件的默认行为。当向下导航时,您从中导航的片段不会被破坏,只有在向上导航时才会被破坏。

就我个人而言,我不明白为什么您想要通知 viewModel 片段已被销毁,但是如果您想在导航到另一个目的地时运行某段代码,您可以在主要活动中使用 NavController.OnDestinationChangedListener (或在您的片段中,但不要忘记在销毁侦听器时删除侦听器),并根据您的开始和结束目的地执行一些操作。

如果您想销毁该片段,您可以尝试更改导航图中导航操作中的“pop to”参数。