从容器中删除所有碎片

Posted

技术标签:

【中文标题】从容器中删除所有碎片【英文标题】:Remove all fragments from container 【发布时间】:2016-01-19 03:31:46 【问题描述】:

有没有办法删除所有已添加特定视图及其视图 ID 的片段?

例如,我想删除添加到 R.id.fragmentcontainer 视图中的所有片段。

【问题讨论】:

Fragments: Remove all fragments in a view的可能重复 【参考方案1】:

它非常简单,只需遍历所有片段并将其删除

for (Fragment fragment : getSupportFragmentManager().getFragments()) 
    getSupportFragmentManager().beginTransaction().remove(fragment).commit();

但如果是导航抽屉,请务必检查它,如果您尝试将其删除,则会出错。

for (Fragment fragment : getSupportFragmentManager().getFragments()) 
  if (fragment instanceof NavigationDrawerFragment) 
      continue;
  
  else  
      getSupportFragmentManager().beginTransaction().remove(fragment).commit();
  

最后但非常重要请务必在进行任何片段事务之前检查 null

for (Fragment fragment : getSupportFragmentManager().getFragments()) 
    if (fragment instanceof NavigationDrawerFragment) 
        continue;
    
    else if (fragment != null) 
        getSupportFragmentManager().beginTransaction().remove(fragment).commit();
    

【讨论】:

谢谢。 NavigationDrawerFragment 是什么?它会很有用,但我认为它来自某个图书馆。 NavigationDrawerFragment 只是作为导航抽屉添加的片段。它不是来自任何其他图书馆。 我遇到了这样一种情况,即 FragmentTransaction add 创建一个普通片段,而 replace 在它上面创建高工具栏(在 Lollipop,带有导航抽屉)。也许你是对的,创建一个虚拟片段和add 其他人会很好。你这样做了吗? 是的,我总是喜欢添加片段作为导航抽屉,它可以更好地控制设计和更改 注意,这将删除给定片段管理器中的 ALL 片段。不只是在 OP 要求的特定布局容器中【参考方案2】:

你可以试试下面的代码

getSupportFragmentManager().beginTransaction().remove(frag).commit(); 

*frag 是要移除的片段对象。

 OR
getFragmentManager().beginTransaction().remove(getFragmentManager().findFragmentById(R.id.your_container)).commit();

它将删除“your_container”容器中的片段。

Happy 编码。

【讨论】:

如何确定碎片对象容器视图是 R.id.mycontainer? 仅供您参考,您可以用您的ID替换。 这是错误的做法。问题不是如何移除一个片段,而是如何移除所有片段。 @Vingtoft 使用:FragmentManager fragmentManager = MainActivity.activity.getSupportFragmentManager(); for(int i = 0; i 感谢您澄清这一点。 @user1632209 应该考虑用您的评论更新答案,这对将来的人们有用。【参考方案3】:

如果有人在 Kotlin 中寻找代码:

supportFragmentManager.apply 
        for (fragment in fragments) 
           beginTransaction().remove(fragment).commit()
        
        popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    

【讨论】:

【参考方案4】:

确实很简单。

private static void removeAllFragments(FragmentManager fragmentManager) 
    while (fragmentManager.getBackStackEntryCount() > 0) 
        fragmentManager.popBackStackImmediate();
    

【讨论】:

这仅在片段被添加到 backstack 时才有效【参考方案5】:

更优化的版本 没有必要多次调用 commit 所以让我们在最后调用一次

supportFragmentManager.fragments.let 
    if (it.isNotEmpty()) 
        supportFragmentManager.beginTransaction().apply 
            for (fragment in it) 
                remove(fragment)
            
            commit()
        
    

【讨论】:

【参考方案6】:

使用此代码

activity?.let 
it.supportFragmentManager.fragments.forEach  fragment ->
        it.supportFragmentManager.beginTransaction().remove(fragment).commit()
    

希望对你有帮助。

谢谢。

【讨论】:

【参考方案7】:

将所有片段保存在 ArrayList 中。

正在初始化:

List<Fragment> activeCenterFragments = new ArrayList<Fragment>();

将片段添加到列表中:

private void addCenterFragments(Fragment fragment) 
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.empty_center_layout, fragment);
    activeCenterFragments.add(fragment);
    fragmentTransaction.commit();

当您想删除全部它们时,请执行以下操作:

private void removeActiveCenterFragments() 
    if (activeCenterFragments.size() > 0) 
        fragmentTransaction = fragmentManager.beginTransaction();
        for (Fragment activeFragment : activeCenterFragments) 
            fragmentTransaction.remove(activeFragment);
        
        activeCenterFragments.clear();
        fragmentTransaction.commit();
    

我多年来一直在生产中使用这种方法,它的作用就像一个魅力。如果您有任何问题,请告诉我。

【讨论】:

如果在你的应用被杀死后状态已经恢复,这将不起作用,因为列表将为空。【参考方案8】:

试试这个,希望对你有帮助:D

try 
if(manager.getFragments()!=null)
    if(manager.getBackStackEntryCount()>0) 
        for (int i = 0; i < manager.getBackStackEntryCount(); i++)
            manager.popBackStack();

        manager.beginTransaction().remove(getSupportFragmentManager()
        .findFragmentById(R.id.main_content))
        .commit();
        
    
catch (Exception e)
    e.printStackTrace();
 

【讨论】:

这个检查是不必要的:" if(manager.getBackStackEntryCount()>0) " 因为如果它是假的,它永远不会在for循环上运行。【参考方案9】:

作为有用答案的补充,我不得不说,如果您向特定的视图容器添加了一些片段,例如:

getSupportFragmentManager()
    .beginTransaction()
    .add(containerViewId, fragmentA)
    .add(containerViewId, fragmentB)
    .commit();

如果您只需将它们替换为一个,您只需调用replace 而无需删除 fragmentAfragmentB

getSupportFragmentManager()
    .beginTransaction()
    .replace(containerViewId, fragment)
    .commit();

根据docsreplace在添加新之前删除所有片段:

替换已添加到容器中的现有片段。这是 本质上与为所有当前调用 remove(Fragment) 相同 添加了使用相同 containerViewId 添加的片段,然后 add(int, Fragment, String) 与此处给出的参数相同。

【讨论】:

这不是正确的方法。导致您无法从容器中删除所有碎片。您只需从最后添加的后堆栈中删除片段

以上是关于从容器中删除所有碎片的主要内容,如果未能解决你的问题,请参考以下文章

从 Angular-ui 引导日期选择器中删除周列和按钮

Docker 从入门到实践系列三 - Docker 常用命令

Docker 从入门到实践系列三 - Docker 常用命令

使用 Powershell 从 Azure 存储子容器中删除所有文件

javascript 从选择器中删除指定的角色

从数字选择器中删除选择