繁体   English   中英

清除除顶部片段以外的片段堆栈

[英]Clear Fragment Backstack except top fragment

在我的应用程序中,我在导航抽屉中有一些菜单项。 当用户点击这些项目之一并导航到相应的片段时,我希望清除他们刚刚导航到的片段之外的片段 backstack。 让我举例说明:

在我的导航抽屉中,用户可以选择打开片段 F1、F2、F3、F4、F5、F6。 首次打开应用程序时,用户按 F1 启动。 假设从 F1 开始,用户使用片段视图本身中的按钮打开片段 F7 -> F8 -> F9 -> F10。 此时,backstack 看起来像:

F1 -> F7 -> F8 -> F9 -> F10

假设从这里,用户打开导航抽屉并选择 F2。 我想要发生的是上面的 backstack 被清除并且只填充了 F2,这样他们的用户就不能从 F2 回到 F10。 换句话说,backstack 应该变成:

不是这个:F1 -> F7 -> F8 -> F9 -> F10 -> F2
但是这个:F2

我怎样才能做到这一点?

编辑 1:我尝试的解决方案之一是在加载活动时将OnNavigationItemSelectedListener添加到导航视图,当按下其中一个项目时会清除后台堆栈。 我的解决方案有效,但在此过程中,我覆盖了实际更改为新片段的默认代码。 我窥探了 Android API 并发现了这个:

navigationView.setNavigationItemSelectedListener(
    new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        boolean handled = onNavDestinationSelected(item, navController);
        if (handled) {
            ViewParent parent = navigationView.getParent();
            if (parent instanceof DrawerLayout) {
                ((DrawerLayout) parent).closeDrawer(navigationView);
            } else {
                BottomSheetBehavior bottomSheetBehavior =
                                    findBottomSheetBehavior(navigationView);
                if (bottomSheetBehavior != null) {
                     bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                }
            }
        }
        return handled;
    }
});

这不是我的代码。 这是处理导航抽屉上菜单项选择的本机代码(在NavigationUI类中找到)。 如果我想添加我自己的OnNavigationItemSelectedListener我将不得不重新创建上面显示的功能,这是我无法做到的,因为那里的某些方法是受保护的。 所以这就是为什么我不相信这个解决方案会奏效。

您可以尝试清除后台堆栈中的片段

FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
    FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
     manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

我希望您在同一个活动中设置所有这些片段。 如果是,那么实现您想要实现的目标并不难。

确保每当您在假设 MainActivity 中设置片段时,请遵循此代码。

val fragmentTransaction = supportFragmentManager.beginTransaction()
if (fragment == null) {
    fragment = Frag2.newInstance()
    fragmentTransaction.replace(R.id.container, fragment, Frag2.TAG)
} else {
    fragmentTransaction.show(fragment)
}
    fragmentTransaction.commit()

实现所需行为的主要逻辑在fragmentTransaction.replace()后面。 因此,每当您在container设置另一个片段时,请使用replace()而不是add()

所以,试试这个并给我反馈。 快乐编码...!

暂无
暂无

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

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