如何从后台弹出片段

Posted

技术标签:

【中文标题】如何从后台弹出片段【英文标题】:How to pop fragment off backstack 【发布时间】:2013-02-04 23:28:06 【问题描述】:

我有一个活动A,它调用片段Bf,它调用片段Cf。我希望在调用 Cf 时将 Bf 放在后台堆栈中,以便用户可以导航回它。但是,如果在 Cf 中按下特定按钮,我希望将 Bf 从后台堆栈中删除。这可能吗?

我看到有一个 popBackStack() 函数。但是,我对这将如何工作感到有些困惑。使用此功能是否安全?是否有可能在后台堆栈的 Bf 之后插入来自不同应用程序的活动?

另外,有什么方法可以改变 backstack 上片段的 savedInstanceState 吗?

我只是不知道如何使用模拟器对 backstack 进行健壮的测试。

【问题讨论】:

避免使用后退栈!它对整体效率并没有真正的帮助!每次要导航时都使用普通的 replace() 甚至更好的删除/添加!查看我在***.com/questions/5802141/…的帖子 @stack_ved 不是一个好主意。 BackStacks 是一个很棒的东西。顺便说一句,我看不到你的帖子。我猜它被否决了。 :P 【参考方案1】:

您可以按名称弹出片段。在将片段添加到后台堆栈时,只需给它们命名即可。

fragmentTransaction.addToBackStack("fragB");
fragmentTransaction.addToBackStack("fragC");

然后在 Fragment_C 中,使用名称 ie..fragB 弹出回栈并包含 POP_BACK_STACK_INCLUSIVE

someButtonInC.setOnClickListener(new View.OnClickListener() 

    @Override
    public void onClick(View v) 

        FragmentManager fm = getActivity()
                .getSupportFragmentManager();
        fm.popBackStack ("fragB", FragmentManager.POP_BACK_STACK_INCLUSIVE);
    
);

【讨论】:

即使我们在 fm.popBackStack 方法中也没有传递任何参数,它也会起作用。 fm.popBackStack(); 如果我想在按下后退按钮时制作它怎么办? @Akki 如果您使用添加到后台堆栈,当您点击后退导航项时,它会弹出最后添加的片段。所以不需要额外的步骤来执行正常的导航返回。只有当您想要执行不同于正常的一步后退导航的操作时,您才需要在按下后退按钮时进行覆盖。 如果那个片段是第一个片段,那么addToBackStackreplace 会导致问题。有什么方法可以在不调用 addToBackStack 的情况下做到这一点? 根据文档“将弹出该状态之前的所有状态”,而不仅仅是特定片段。【参考方案2】:

从 BackStack 中弹出 Fragment 的三种方法

只需添加以下任何一行:

1)

getActivity().getSupportFragmentManager().popBackStack();

2)

getActivity().getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

3)

getActivity().getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

它们都是从 Backstack 中弹出片段的简单方法

【讨论】:

非常感谢你hhhh!在覆盖 onbackpressed 之后,这真的帮助我回去了。我搜索了大约一个小时【参考方案3】:

首先替换片段 container_view 时我们添加名称,如“Later Transaction”

   getSupportFragmentManager().beginTransaction().replace(R.id.container_view, 
    profileFragment, "Profile").addToBackStack("Later Transaction").commit();

然后在后按按钮时使用后来的事务名称弹出返回堆栈

     int count = getSupportFragmentManager().getBackStackEntryCount();
    if(count > 1) 
     getSupportFragmentManager().popBackStack("Later Transaction", 
     FragmentManager.POP_BACK_STACK_INCLUSIVE);
     else 
        DialogUtils.show(HomeActivity.this, 
        getString(R.string.exit_app_message), getString(R.string.alert), 
       "Yes","No", new DialogUtils.ActionListner() 
            @Override
            public void onPositiveAction() 
                finish();
            
            @Override
            public void onNegativeAction() 
            
        );
    

【讨论】:

管理碎片的回栈条目计数的绝佳解决方案【参考方案4】:

这是使用BackStackEntry弹出最后一个片段的示例

val manager = supportFragmentManager
try 
    // get last entry (you can get another if needed)
    val entry = manager.getBackStackEntryAt(manager.backStackEntryCount - 1)
    // you can pop it by name
    manager.popBackStack(entry.name, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    // or pop by id
    manager.popBackStack(entry.id, FragmentManager.POP_BACK_STACK_INCLUSIVE)
 catch (ex: Exception) 
    ex.printStackTrace()

【讨论】:

以上是关于如何从后台弹出片段的主要内容,如果未能解决你的问题,请参考以下文章

组件导航,带参数从后台弹出

从后台弹出时不调用 Fragment 的 onResume()

来自后台堆栈的片段 onResume

如何知道何时调用了`navController.popBackStack()`?

从后台堆栈恢复片段时的 savedInstanceState

如何在片段 kotlin 中编写 onBackPressed()