Remove old Fragment from fragment manager
Asked Answered
I

7

83

I'm trying to learn how to use Fragments in android. I'm trying to remove old fragment when new fragment is calling in android.

Irreproachable answered 18/3, 2014 at 9:4 Comment(0)
G
194

You need to find reference of existing Fragment and remove that fragment using below code. You need add/commit fragment using one tag ex. "TAG_FRAGMENT".

Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);
if(fragment != null)
    getSupportFragmentManager().beginTransaction().remove(fragment).commit();

That is it.

Groundless answered 18/3, 2014 at 9:14 Comment(5)
Is fragment also not work using stack mechanism? Or is back stack just if we use it? Or does this technique move fragments on top and then remove the fragment and put the fragments back or something?Cm
@SreekanthKarumanaghat: Yes, You can use pop back stack. But it will remove top most fragment in context. But if you want remove specific fragment from container you can use remove method.Groundless
My question was that how does this method work?Is my understanding of how the fragments work right? Fragment 1-> Fragment 2 -> Fragment 3 Does this mean that the Fragments are kept in a stack or is the back stack just maintained as a custom mechanism?Cm
@SreekanthKarumanaghat Yes, Fragment can be maintained in stack. But for that you need to tell fragment manager to add them in stack. Refer: developer.android.com/reference/android/app/…Groundless
Just wanted to add that by commit schedules it to be executed on the next run loop. If you need it removed immediately, you can call fragmentManager.executePendingTransactions()Curable
U
10

I had the same issue. I came up with a simple solution. Use fragment .replace instead of fragment .add. Replacing fragment doing the same thing as adding fragment and then removing it manually.

getFragmentManager().beginTransaction().replace(fragment).commit();

instead of

getFragmentManager().beginTransaction().add(fragment).commit();
Ugh answered 2/8, 2018 at 12:54 Comment(0)
P
9

I had the same issue to remove old fragments. I ended up clearing the layout that contained the fragments.

LinearLayout layout = (LinearLayout) a.findViewById(R.id.layoutDeviceList);
layout.removeAllViewsInLayout();
FragmentTransaction ft = getFragmentManager().beginTransaction();
...

I do not know if this creates leaks, but it works for me.

Pattani answered 8/7, 2015 at 10:2 Comment(4)
This actually is a great approach.Lashing
But this will remove the fragment which is included in xml and used programmatically by it's ID to replace the fragments.Sharenshargel
This only removes the fragment's views from the layout. The fragment itself is still attached to the fragment manager and is not stopped, detached, or destroyed.Doherty
Perfect solution to remove views added programmatically inside a layout!Stood
T
2

Probably you instance old fragment it is keeping a reference. See this interesting article Memory leaks in Android — identify, treat and avoid

If you use addToBackStack, this keeps a reference to instance fragment avoiding to Garbage Collector erase the instance. The instance remains in fragments list in fragment manager. You can see the list by

ArrayList<Fragment> fragmentList = fragmentManager.getFragments();

The next code is not the best solution (because don´t remove the old fragment instance in order to avoid memory leaks) but removes the old fragment from fragmentManger fragment list

int index = fragmentManager.getFragments().indexOf(oldFragment);
fragmentManager.getFragments().set(index, null);

You cannot remove the entry in the arrayList because apparenly FragmentManager works with index ArrayList to get fragment.

I usually use this code for working with fragmentManager

public void replaceFragment(Fragment fragment, Bundle bundle) {

    if (bundle != null)
        fragment.setArguments(bundle);

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment oldFragment = fragmentManager.findFragmentByTag(fragment.getClass().getName());

    //if oldFragment already exits in fragmentManager use it
    if (oldFragment != null) {
        fragment = oldFragment;
    }

    fragmentTransaction.replace(R.id.frame_content_main, fragment, fragment.getClass().getName());

    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

    fragmentTransaction.commit();
}
Territorial answered 28/3, 2017 at 10:2 Comment(0)
P
1

I had issue with fragment onBackPress. I didn't want to return to old fragments.

This solution worked for me to remove old fragments from fragment manager :

FragmentManager fm = getSupportFragmentManager();
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

You can also use an if block like this :

FragmentManager fm = getSupportFragmentManager();

if (fm.getBackStackEntryCount() > 0) {
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
Pietro answered 23/1, 2022 at 6:25 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Appellative
L
0

I was facing the same error with few views so I set the visibility of reductant views as GONE. This method solved my issue as charm.

<View>.setVisibility(View.GONE); 
Linger answered 24/8, 2022 at 6:24 Comment(0)
F
-1

In Kotlin

  val fragList  = f.supportFragmentManager.fragments
    for (fragment in fragList) {
        f.supportFragmentManager.beginTransaction().remove(fragment).commit()
    }
Fordo answered 5/4, 2022 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.