10

I have a layout for landscape mode that shows a ListView on the left and a FrameLayout on the right. When an item is selected from the list another fragment is added to the FrameLayout

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.myFrameLayout);
FragmentTransaction ft = fragmentManager.beginTransaction();
if (myFragment == null) {
    myFragment = new MyFragment(uri);
    ft.replace(R.id.myFrameLayout, playerFragment);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    ft.commitAllowingStateLoss();
}

Later on I press delete in the list view and remove the last item in the list, and I try to remove the fragment so that nothing is shown, but it doesn't work, my fragment remains on the screen. The code for removing is:

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentById(R.id.myFrameLayout);
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.remove(myFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
ft.commitAllowingStateLoss();

Any ideas why it is not being removed from the View?

DaveJohnston
  • 10,031
  • 10
  • 54
  • 83

6 Answers6

15

@DaveJohnston I have tried your code for remove fragment I just molded....thanks :)

Hey I dont know this is solution to your problem or not but you try this way it will work:

Approach to add fragment:

YourFragment yourFrament;

//Add your Fragment
public void addYourFragment(){
yourFragment = new YourFragment();

FragmentTransaction transation = getSupportFragmentManager().beginTransaction();
transation.replace(R.id.yourFlowLayout, yourFragment);

        transation.commit();

}   

Approach to remove Fragment:

 //Remove Fragment
    public void removeYourFragment(){
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            if (yourFragment != null) {           
                transaction.remove(yourFragment);
                transaction.commit();
                transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
                yourFragment = null;
            }
    }
Gru
  • 2,686
  • 21
  • 29
3

are you declaring the fragment in xml? Citing Dianne Hackborn from google:

Defining fragments in XML is mostly intended for things that are going to stay around. If you are going to add and remove, you should probably consistently do it dynamically.

hope it helps

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • I think he is referring to using the tag in the XML layout. I am not using that, I am using a FrameLayout as a placeholder and dynamically updating the fragment that is put into it. I might try using the FragmentTransaction.hide() method that was mentioned in the thread you referenced though. – DaveJohnston Mar 28 '12 at 18:45
  • Well this API is just bad. You do a simple `remove()` call, and the very basic thing you were expecting it to do does not work. – milosmns May 23 '16 at 17:18
  • It does work for fragments added with an explicit transaction,made by you, programmatically. – Blackbelt May 23 '16 at 17:24
0

When You finding Your fragment by Id you got reference to fragment container not fragment itself. Use a TAG when you addiing fragment and then finding by TAG:

MyFragment myFragment = (MyFragment) fragmentManager.findFragmentByTag("yourTag");
Arvis
  • 8,273
  • 5
  • 33
  • 46
0

I had a very hard time finding a SO reference to this issue occurring when NOT setting <fragment> via XML, but indeed setting every Fragment dynamically with FragmentTransaction and <FrameLayout>.

Simplifying Gru's solution, what solved it for me was was simply adding .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) to my replace transaction and it worked! Previous fragments are now actually hidden from view.

I imagine other transitions would work as well.

Vishwajit Palankar
  • 3,033
  • 3
  • 28
  • 48
jschlepp
  • 91
  • 5
0
private static String TAG_FRAGMENT="MyFragment";
MyFragment myFragment = (MyFragment)   fragmentManager.findFragmentById(R.id.myFrameLayout);
 FragmentTransaction ft = fragmentManager.beginTransaction();
 if (myFragment == null) {
      myFragment = new MyFragment(uri);
     ft.replace(R.id.myFrameLayout, playerFragment,TAG_FRAGMENT);
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
     ft.addToBackStack(TAG_FRAGMENT);
     ft.commit();
 }

when replacing your fragment to use ft.addToBackStack(null) method after easily remove your fragment.

Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);

if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
jinkal
  • 1,622
  • 16
  • 21
0

If you have a Fragment that is not removed on replacing the Fragment in the FrameLayout? you can remove it by commit a separate removal transition with FragmentTransaction.TRANSIT_FRAGMENT_CLOSE on it before a call to the regular replace commit.

Fragment removeThisFragment;//Keep a reference to the fragment you want to remove
...
 FragmentManager fragmentManager =  getSupportFragmentManager();
 FragmentTransaction transaction =  fragmentManager.beginTransaction();

 // This fragment "sometimes" do not get replaced so we remove it here if it's added.
        if(removeThisFragment!=null&&removeThisFragment.isAdded()) {
            transaction =  fragmentManager.beginTransaction();
            transaction.remove(removeThisFragment);
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
            transaction.commitAllowingStateLoss();
        }

        // update the main content by replacing fragments
        transaction =  fragmentManager.beginTransaction();
        transaction.replace(R.id.content_frame, fragment, TAG_MAIN_FRAGMENT).commit();

But I suggest to try and figure out first why the Fragment is not replaced in the first place, check if it's doing some heavy work or something keeping it from getting replaced?? but if you need a quick temporary fix try the above code.

TouchBoarder
  • 6,422
  • 2
  • 52
  • 60