64

Is there a way to remove all fragments which are already added the specific view with its view id?

For example I want to remove all fragments which are added into R.id.fragmentcontainer view.

aligur
  • 3,387
  • 3
  • 34
  • 51
  • Possible duplicate of [Fragments: Remove all fragments in a view](http://stackoverflow.com/questions/14764043/fragments-remove-all-fragments-in-a-view) – ThomasThiebaud Oct 20 '15 at 12:55

10 Answers10

97

Its very simple just loop through all the fragments and remove it

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

But in case of Navigation Drawer be sure to check it, if you try to remove it you will get error.

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

Last but very important be sure to check for null before doing any fragment transactions

for (Fragment fragment : getSupportFragmentManager().getFragments()) {
    if (fragment instanceof NavigationDrawerFragment) {
        continue;
    }
    else if (fragment != null) {
        getSupportFragmentManager().beginTransaction().remove(fragment).commit();
    }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Sumit Saxena
  • 1,152
  • 9
  • 7
  • Thanks. What is `NavigationDrawerFragment`? It will be useful, but I think, it is from some library. – CoolMind Dec 01 '16 at 20:25
  • NavigationDrawerFragment is simply a fragment added as nav drawer. It is not from any other library. – Sumit Saxena Dec 02 '16 at 06:47
  • I faced a situation where a FragmentTransaction `add` creates a normal fragment, while `replace` makes tall toolbar over it (at Lollipop, with navigation drawer). Maybe you are right, it would be good to create a dummy fragment and `add` others. Have you done so? – CoolMind Dec 02 '16 at 10:33
  • yes i always prefer adding fragment as navigation drawer, it gives more control over design and changes – Sumit Saxena Dec 02 '16 at 10:45
  • 11
    Beware, this will remove **ALL** fragments in the given fragment manager. Not just in a particular layout container as OP was asking – Subaru Tashiro Oct 03 '18 at 05:42
  • I think you can use reuse existing transaction while removing fragments in the loop, no need to begin new one every time. – Vadim Kotov Jun 19 '19 at 16:08
14

In case someone is looking for a code in Kotlin:

supportFragmentManager.apply {
        for (fragment in fragments) {
           beginTransaction().remove(fragment).commit()
        }
        popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
    }
akhil nair
  • 1,371
  • 1
  • 11
  • 19
Devrath
  • 42,072
  • 54
  • 195
  • 297
8

It is indeed very simple.

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

More optimized version
There is no need in multiple call of commit so lets call it one time at the end

supportFragmentManager.fragments.let {
    if (it.isNotEmpty()) {
        supportFragmentManager.beginTransaction().apply {
            for (fragment in it) {
                remove(fragment)
            }
            commit()
        }
    }
}
Vlad
  • 7,997
  • 3
  • 56
  • 43
3

Use this code

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

Hope it helps.

Thank you.

Ajay Nishad
  • 361
  • 1
  • 3
  • 10
2

Save all your fragments in an ArrayList.

Initializing:

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

Adding fragment to list:

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

When you want to remove all them, do the following:

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

I have used this method in production for years, and it works like a charm. Let me know if you have any questions.

Vingtoft
  • 13,368
  • 23
  • 86
  • 135
2

Try this, hope it helps :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();
} 
Gian_DC
  • 21
  • 1
  • This check is unnecessary: " if(manager.getBackStackEntryCount()>0) { " since it will never run a pass on the for loop anyway if this is false. – Erik Jul 17 '17 at 06:55
1

As an addition to useful answers I have to say that if you have added few fragments to specific view container, for example:

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

and if you need just replace them by one, you can simply call replace without removing fragmentA and fragmentB

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

According to the docs replace removes all fragments before adding new:

Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

remain4life
  • 1,201
  • 2
  • 12
  • 11
  • this is not correct way. cause you couldnt remove all fragments from the container. you only remove the fragment from the back stack which added last – aligur Jan 14 '21 at 05:39
1

This Kotlin extension does the job:

fun FragmentManager.removeAll(containerId: Int) {
    beginTransaction().apply {
        fragments.filter {
            it.id == containerId
        }.forEach {
            remove(it)
        }
    }.commit()
}
Semyon Tikhonenko
  • 3,872
  • 6
  • 36
  • 61
1

Here is much simplier way to clear all fragments from Fragment Container View

view.findViewById(R.id.fragmentcontainer).removeAllViews()

if you are using viewbinding then

binding.fragmentcontainer.removeAllViews()
Nabeel
  • 841
  • 1
  • 10
  • 23