简体   繁体   English

如何将 android 导航 backstack 弹出到某个片段?

[英]How do I pop android navigation backstack up to a certain fragment?

I am once again asking for your intellectual support.我再次请求您的智力支持。

I have a fragment that puts a number of copies of itself on the navigation backstack like this:我有一个片段,它把自己的许多副本放在导航 backstack 上,如下所示:

Navigation.findNavController(button).navigate(
    TaskCollectFragmentDirections.actionTaskCollectFragmentSelf(args.taskIndex, args.screenIndex + 1)
)

The code above works as intended.上面的代码按预期工作。

The problem comes, when I want to pop a specified number of these fragments off the navigation backstack.当我想从导航堆栈中弹出指定数量的这些片段时,问题就来了。 (Triggered by a buttonpress.) (由按下按钮触发。)

I've tried to do it like this:我试过这样做:

Navigation.findNavController(button).popBackStack(lastRecurringFragmentId, false)

My code compiles and runs, but simply does nothing.我的代码编译并运行,但什么也不做。 When I give no parameters to the popBackStack function, it properly pops off the topmost fragment.当我没有为popBackStack function 提供任何参数时,它会正确弹出最顶部的片段。 I can also use the back arrow to navigate back all the way to the starting fragment.我还可以使用后退箭头一直导航到起始片段。

If it is of any importance, the lastRecurringFragmentId comes from this function:如果它很重要, lastRecurringFragmentId来自这个 function:

fun getLastRecurringFragmentId(recurringFragmentCount: Int): Int {
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
    val backStackEntryCount = navHostFragment.childFragmentManager.backStackEntryCount
    val indexOfRequested = backStackEntryCount - recurringFragmentCount
    val requestedEntry = navHostFragment.childFragmentManager.getBackStackEntryAt(indexOfRequested)
    return requestedEntry.id
}

The navigation graph is as follows.导航图如下。 There are supposed to be several TaskCollectFragment s and lastly one TaskEndFragment on the top of the backstack.应该有几个TaskCollectFragment s,最后一个TaskEndFragment在 backstack 的顶部。 I want to pop some of the TaskCollectFragment s off the stack when the user presses a button on the TaskEndFragment :当用户按下TaskEndFragment上的按钮时,我想将一些TaskCollectFragment从堆栈中弹出:

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

    <fragment
        android:id="@+id/nav_home"
        android:name="ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_nav_home_to_taskCollectFragment"
            app:destination="@id/taskCollectFragment" />
    </fragment>

    <fragment
        android:id="@+id/taskCollectFragment"
        android:label="TaskCollectFragment"
        tools:layout="@layout/task_collect_fragment"
        >
        <action
            android:id="@+id/action_taskCollectFragment_to_taskEndFragment"
            app:destination="@id/taskEndFragment" />
        <action
            android:id="@+id/action_taskCollectFragment_self"
            app:destination="@id/taskCollectFragment" />
        <argument
            android:name="taskIndex"
            app:argType="integer" />
        <argument
            android:name="screenIndex"
            app:argType="integer" />
    </fragment>
    <fragment
        android:id="@+id/taskEndFragment"
        android:name="ui.task.TaskEndFragment"
        android:label="TaskEndFragment"
        tools:layout="@layout/task_end_fragment">
        <argument
            android:name="taskIndex"
            app:argType="integer" />
    </fragment>
</navigation>

Is there a way I can pop fragments off the backstack until a certain condition is met?有没有办法可以在满足特定条件之前从后台弹出碎片?

I created two almost identical fragments, forSessionTaskCollectFragment and recurringTaskCollectFragment with the same viewModel.我创建了两个几乎相同的片段, forSessionTaskCollectFragmentrecurringTaskCollectFragment具有相同的视图模型。 They look the same and from the user's point of view they do the same.它们看起来是一样的,从用户的角度来看它们也是一样的。 The forSessionTaskCollectFragment s are the ones I want to keep and the recurringTaskCollectFragment s are the ones I want to pop back later. forSessionTaskCollectFragment是我想要保留的,而recurringTaskCollectFragment是我以后想要弹出的。

From the home fragment, my navigation graph goes to the forSessionTaskCollectFragment , from there it loops back on itself or goes to the recurringTaskCollectFragment which also loops back to itself or finally goes to the TaskEndFragment从主片段,我的导航图转到forSessionTaskCollectFragment ,从那里它循环回自身或转到recurringTaskCollectFragment ,它也循环回自身或最后转到TaskEndFragment

<fragment
    android:id="@+id/nav_home"
    android:name="ui.home.HomeFragment"
    android:label="@string/menu_home"
    tools:layout="@layout/fragment_home" >
    <action
        android:id="@+id/action_nav_home_to_orSessionTaskCollectFragment"
        app:destination="@id/forSessionTaskCollectFragment" />
</fragment>

<fragment
    android:id="@+id/forSessionTaskCollectFragment"
    android:name="ui.task.ForSessionTaskCollectFragment"
    android:label="ForSessionTaskCollectFragment" >
    <action
        android:id="@+id/action_forSessionTaskCollectFragment_self"
        app:destination="@id/forSessionTaskCollectFragment" />
    <action
        android:id="@+id/action_forSessionTaskCollectFragment_to_recurringTaskCollectFragment"
        app:destination="@id/recurringTaskCollectFragment" />
    <argument
        android:name="taskIndex"
        app:argType="integer" />
    <argument
        android:name="screenIndex"
        app:argType="integer" />
</fragment>

<fragment
    android:id="@+id/recurringTaskCollectFragment"
    android:name="ui.task.RecurringTaskCollectFragment"
    android:label="TaskCollectFragment"
    tools:layout="@layout/recurring_task_collect_fragment"
    >
    <action
        android:id="@+id/action_recurringTaskCollectFragment_to_taskEndFragment"
        app:destination="@id/taskEndFragment" />
    <action
        android:id="@+id/action_recurringTaskCollectFragment_self"
        app:destination="@id/recurringTaskCollectFragment" />
    <argument
        android:name="taskIndex"
        app:argType="integer" />
    <argument
        android:name="screenIndex"
        app:argType="integer" />
</fragment>

I put forSessionTaskCollectFragment s on the stack until I get to the point to which I want to return.我将forSessionTaskCollectFragment放在堆栈上,直到到达我想要返回的位置。

Navigation.findNavController(button).navigate(
    if(args.screenIndex < viewModel.forSessionScreenCount) {
        ForSessionTaskCollectFragmentDirections.actionForSessionTaskCollectFragmentSelf(args.taskIndex, args.screenIndex + 1)
    } else {
        ForSessionTaskCollectFragmentDirections.actionForSessionTaskCollectFragmentToRecurringTaskCollectFragment(args.taskIndex, args.screenIndex + 1)
    }
)

After that I put the fragments I later want to pop back, and finally go to the TaskEndFragment from where I want to pop the fragments I need to:之后,我将稍后要弹出的片段,最后将 go 放到我想要弹出片段的TaskEndFragment中:

Navigation.findNavController(button).navigate(
    if(args.screenIndex < viewModel.screenCount - 2) {
        RecurringTaskCollectFragmentDirections.actionRecurringTaskCollectFragmentSelf(args.taskIndex, args.screenIndex + 1)
    } else {
        RecurringTaskCollectFragmentDirections.actionRecurringTaskCollectFragmentToTaskEndFragment(args.taskIndex)
    }
)

So on the TaskEndFragment 's buttonpress I can pop back to the exact place on the backstack that I marked with changing from "session" fragments to "recurring" fragments:因此,在TaskEndFragment的按钮按下时,我可以弹回后台堆栈上我标记为从“会话”片段更改为“重复”片段的确切位置:

Navigation.findNavController(button).popBackStack(R.id.forSessionTaskCollectFragment, false)

This was a lot of hassle, I did not find any example for the thing I wanted to do, but finally managed to come up with a working solution.这很麻烦,我没有找到任何我想做的事情的例子,但最终设法想出了一个可行的解决方案。 Ianhanniballake thanks again, you triggered my idea. Ianhanniballake 再次感谢,你激发了我的想法。

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

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