繁体   English   中英

如何从片段导航组件的后台堆栈中仅删除一个片段?

[英]How to remove only one fragment from backstack in fragment navigation component?

在我的应用程序中,我使用了一个活动和四个片段。 在这个应用程序中,我使用了导航组件。 我的片段加载顺序是 A->B->C->D

在片段 D On device back button press 我想从 backstack 中删除片段 C 以便片段 B 可以打开。 任何人都建议我该怎么做 提前谢谢你

这是我的 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/navigation_graph"

    app:startDestination="@id/firstFragment"
    >
    <fragment
        android:id="@+id/firstFragment"
        android:name="com.education.javaprogramming.fragments.MainFragment"
        android:label="fragment_first"
        tools:layout="@layout/activity_main" >

        <action
            android:id="@+id/action_firstFragment_to_displayList1Fragment"
            app:destination="@id/displayList1Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_firstFragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <action
            android:id="@+id/action_firstFragment_to_helpFragment"
            app:destination="@id/helpFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_firstFragment_to_quizzFragment"
            app:destination="@id/quizzFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/displayList1Fragment"
        android:name="com.education.javaprogramming.fragments.DisplayList1Fragment"
        android:label="fragment_display_list1"
        tools:layout="@layout/fragment_display_list1"

        >
        <argument
            android:name="position1"
            app:argType="integer" />
        <action
            android:id="@+id/action_displayList1Fragment_to_firstFragment"
            app:destination="@id/firstFragment" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_displayList1Fragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"


            />
    </fragment>
    <fragment
        android:id="@+id/displayList2Fragment"
        android:name="com.education.javaprogramming.fragments.DisplayList2Fragment"
        android:label="fragment_display_list2"
        tools:layout="@layout/fragment_display_list2" >
        <action
            android:id="@+id/action_displayList2Fragment_to_displayList1Fragment"
            app:destination="@id/displayList1Fragment"

            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <action
            android:id="@+id/action_displayList2Fragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="position2"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_displayList2Fragment_to_displayListInDeFragment"
            app:destination="@id/displayListInDeFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/displayListInDeFragment"
        android:name="com.education.javaprogramming.fragments.DisplayListInDeFragment"
        android:label="fragment_display_list_in_de"
        tools:layout="@layout/fragment_display_list_in_de" >
        <action
            android:id="@+id/action_displayListInDeFragment_to_displayList2Fragment"
            app:destination="@id/displayList2Fragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="position2"
            app:argType="integer" />
        <argument
            android:name="position3"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
    </fragment>
    <fragment
        android:id="@+id/helpFragment"
        android:name="com.education.javaprogramming.fragments.HelpFragment"
        android:label="fragment_help"
        tools:layout="@layout/fragment_help" >
        <action
            android:id="@+id/action_helpFragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <argument
            android:name="name"
            app:argType="string" />
        <action
            android:id="@+id/action_helpFragment_to_aboutFragment"
            app:destination="@id/aboutFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
    </fragment>
    <fragment
        android:id="@+id/aboutFragment"
        android:name="com.education.javaprogramming.fragments.AboutFragment"
        android:label="fragment_about"
        tools:layout="@layout/fragment_about" >
        <action
            android:id="@+id/action_aboutFragment_to_helpFragment"
            app:destination="@id/helpFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"
            />
    </fragment>
    <fragment
        android:id="@+id/quizzFragment"
        android:name="com.education.javaprogramming.fragments.QuizzFragment"
        android:label="fragment_quizz"
        tools:layout="@layout/fragment_quizz" >
        <action
            android:id="@+id/action_quizzFragment_to_firstFragment"
            app:destination="@id/firstFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <action
            android:id="@+id/action_quizzFragment_to_displayExamFragment"
            app:destination="@id/displayExamFragment" />
    </fragment>
    <fragment
        android:id="@+id/displayExamFragment"
        android:name="com.education.javaprogramming.fragments.DisplayExamFragment"
        android:label="fragment_display_exam"
        tools:layout="@layout/fragment_display_exam" >
        <action
            android:id="@+id/action_displayExamFragment_to_quizzFragment"
            app:destination="@id/quizzFragment"
            app:enterAnim="@anim/enter"
            app:exitAnim="@anim/exit"
            app:popEnterAnim="@anim/pop_enter"
            app:popExitAnim="@anim/pop_exit"

            />
        <argument
            android:name="position1"
            app:argType="integer" />
        <action
            android:id="@+id/action_displayExamFragment_to_resultFragment"
            app:destination="@id/resultFragment" />
    </fragment>
    <fragment
        android:id="@+id/resultFragment"
        android:name="com.education.javaprogramming.fragments.ResultFragment"
        android:label="fragment_result"
        tools:layout="@layout/fragment_result" >
        <action

            android:id="@+id/action_resultFragment_to_quizzFragment"
            app:destination="@id/quizzFragment" />
        <argument android:name="givenAnswers"
            app:argType="reference"
            />
        <argument android:name="actualAnswers"
            app:argType="reference"
            />
    </fragment>


</navigation>

您可以使用navController.popBackStack(int destinationId,bool inclusive)方法,(请注意boolean值)

尝试将控制器的返回堆栈弹出回特定目标。 例如。

navController.popBackStack(R.id.dest_id_of_B, true)

你应该使用

      app:popUpTo="@id/id_of_c_fragment" 
      app:popUpToInclusive="true"
      app:popUpTo="@id/id_of_d_fragment"
      app:popUpToInclusive="true"

在操作范围内的导航图中。

在fragment D中,如果要回到fragment B(移除fragment C),可以使用:

Navigation.findNavController(requireView()).popBackStack(
    R.id.id_of_fragment_C, true)

id_of_fragment_C是要跳过的片段的 id。

好吧,我有同样的问题,但你解决了这样

    <action
        android:id="@+id/id_action"
        app:destination="@id/fragment_D"
        app:launchSingleTop="true"
        app:popUpTo="@id/fragment_B"
        app:popUpToInclusive="true" />

我需要一个类似的场景
验证屏幕 (A) 上的用户必须通过说明屏幕 (B) 和上传屏幕 (C)。

在这里,是所需的导航旅程

  • 向前导航A > B > C
  • 返回导航A < C
  • 在 Fragment-C 上成功上传后导航A < C

因此,为了实现这一点,这是我必须编写的导航操作。

导航 A > B,简单导航
<action
android:id="@+id/action_verification_to_upload_info"
app:destination="@id/navigation_upload_info" />
导航 B > C

导航弹回并包含 B,结果登陆 A。

<action android:id="@+id/action_id_upload_info_to_verification_upload"
app:popUpTo="@id/action_verification_to_upload_info"
app:popUpToInclusive="true"
app:destination="@id/navigation_id_verification_upload" />

请注意app:popUpTo的值为Fragment B的 navID 和app:popUpToInclusive="true"

这对我来说就像一个魅力!

如果您知道必须返回 go 的目的地,我会推荐您@Bharatesh 的答案;

如果您更喜欢 XML 方式,或者 @sudo007 的答案。

如果您不知道用户从哪里导航到当前屏幕,因为到当前目的地的路径不止一条,请尝试以下操作:

button.setOnClickListener {
        val navController= it.findNavController()
        navController.previousBackStackEntry?.let { backEntry -> navController.popBackStack(backEntry.destination.id,true) }
    }

这将动态检索您以前的返回堆栈条目,并从您的返回堆栈中弹出当前和以前的目的地。

这里的true是让它包含要从 backStack 弹出的书面目的地。

如果 lambda 表达式难以理解,请尝试以下代码:

val navController = it.findNavController()
    val prevId = navController.previousBackStackEntry?.destination?.id
    if (prevId != null) {
        navController.popBackStack(prevId, true)
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM