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

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

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

【问题讨论】:

标签: android android-fragments


【解决方案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) 与此处给出的参数相同。

        【讨论】:

        • 这不是正确的方法。导致您无法从容器中删除所有碎片。您只需从最后添加的后堆栈中删除片段
        猜你喜欢
        • 2011-09-09
        • 1970-01-01
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多