使用导航组件从后台删除片段

jam*_*s04 1 android-fragments kotlin android-architecture-navigation android-jetpack-navigation android-navigation-graph

我有一个带有 navHost 片段的 PinCreateActivity 和 2 个片段 PinSetup 和 PinCreate 片段。

当 Activity 启动时,PinSetup 是默认片段,之后通过单击按钮导航到 PinCreate 片段。我想要的是来自 PinCreate 片段,当用户单击后退按钮时,不要像 PinCreateActivity 那样转到 PinSetup 并导航到后退堆栈。所以我想当我从 PinSetup 导航到 PinCreate 片段时,我必须从 backStack 中删除 PinSetup。我怎样才能做到这一点?

导航图.xml

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

    <fragment
        android:id="@+id/pinSetupFragment"
        android:name="com.example.ui.fragments.pin.PinSetupFragment"
        android:label="Create PIN"
        tools:layout="@layout/fragment_pin_setup" >
        <action
            android:id="@+id/action_pinSetupFragment_to_pinCreateFragment"
            app:destination="@id/pinCreateFragment" />
    </fragment>
    <fragment
        android:id="@+id/pinCreateFragment"
        android:name="com.example.ui.fragments.pin.PinCreateFragment"
        android:label="Your PIN"
        tools:layout="@layout/fragment_pin_create" />
</navigation>
Run Code Online (Sandbox Code Playgroud)

Pin创建活动

private lateinit var navController: NavController

 override fun onCreate(savedInstanceState: Bundle?) {
 
    ...
    navController = Navigation.findNavController(this, R.id.pin_create_host_fragment)


    // onClick
    navController.navigate(R.id.action_pinSetupFragment_to_pinCreateFragment)

 }
Run Code Online (Sandbox Code Playgroud)

Ber*_*ber 8

如果您在执行弹出操作时需要一些额外的逻辑,则可以通过 Kotlin 代码以编程方式执行此操作。但如果您只需要从PinSetupFragment返回堆栈中删除,则可以在导航图 xml 文件中执行此操作。

因此,如果您只是要弹出片段而不需要任何其他额外的逻辑,那么从返回堆栈弹出的最佳方法PinSetupFragment是更新您的navigation_graph.xml文件。

只需将这两行添加到您的操作中即可:

app:popUpTo="@id/pinSetupFragment"
app:popUpToInclusive="true"
Run Code Online (Sandbox Code Playgroud)

结果,你的navigation_graph.xml文件将是这样的:

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

    <fragment
        android:id="@+id/pinSetupFragment"
        android:name="com.example.ui.fragments.pin.PinSetupFragment"
        android:label="Create PIN"
        tools:layout="@layout/fragment_pin_setup" >
        <action
            android:id="@+id/action_pinSetupFragment_to_pinCreateFragment"
            app:destination="@id/pinCreateFragment"
            app:popUpTo="@id/pinSetupFragment"
            app:popUpToInclusive="true" />
    </fragment>
    <fragment
        android:id="@+id/pinCreateFragment"
        android:name="com.example.ui.fragments.pin.PinCreateFragment"
        android:label="Your PIN"
        tools:layout="@layout/fragment_pin_create" />
</navigation>
Run Code Online (Sandbox Code Playgroud)

  • 是的,你是对的,这可以做同样的事情,因为你有两个片段。但这会弹出此 nav_graph 内的所有先前片段。因此,如果您只需要弹出 1 个片段,并且有 3 个或更多片段,则应该使用要弹出的片段的 id。 (2认同)