mt0s
mt0s

Reputation: 5811

Confused with remove Fragment

I have an Activity with a Button and a FrameLayout in its layout. When I click the Button I add the fragment to the Activity's View. If I add the fragment to the Back stack with addToBackStack() when I click the Back button it dissapears. I want to achieve the same functionality by clicking again the Button.

My code is this :

     button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {

             AddRemoveFragment Frag_A = new AddRemoveFragment();

             FragmentManager fm1 = getSupportFragmentManager();
             FragmentTransaction transaction = fm1.beginTransaction();

        if ( state == 0 ) {
                 Log.i(TAG, "inside IF");
                 state=1;
                 transaction.add(R.id.fragment_container_1, Frag_A);
                 transaction.addToBackStack(null);
                 transaction.commit();

             } else {
                 state=0;
                 Log.i(TAG, "inside ELSE");
                 //transaction.replace(R.id.fragment_container_1, Frag_A);
                     transaction.remove(Frag_A);
                 transaction.commit();
             }

         }
     });

Both remove() and hide() do nothing. From the reference I don't understand something more specific. Just says it removes the fragment from the container. Isn't this what I want?Remove the fragment from FrameLayout?

Edit: hope it has nothing to do with the support library. I saw someone having some problems with that. Here

XML :

<?xml version="1.0" encoding="utf-8"?>

<Button
    android:id="@+id/button_frag_1"
    android:layout_width="124dp"
    android:layout_height="wrap_content"
    android:text="@string/button_text_1" />

<FrameLayout
    android:id = "@+id/fragment_container_1"
    android:layout_width="80dp"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/button_frag_1"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/button_frag_1" >
</FrameLayout>

Edit 2: I changed the code inside the else statement from transaction.replace(R.id.fragment_container_1, Frag_A); to transaction.remove(Frag_A); but still got the same functionality.

Upvotes: 3

Views: 2076

Answers (1)

Emil Adz
Emil Adz

Reputation: 41129

For fragments, first of all you need to remember one thing: If you added your fragment in your XML layout, then it can't be removed, it can only be shown using the .show() method and hidden using the .hide() method. If on the other hand you create an instance of your fragment in your code then you should add it using the .add() method or remove it using the .remove() method.

As regard to your question, I dont think you need to add your fragment to back stack if you want to remove your fragment using your button (unless you want to keep the functionality of removing it using the 'back' button).

In addition I don't think you need to use replace, from the documentation of replace:

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.

It means that it replaces the content of the container with the new fragment, so all you do is remove your fragment and add it again.

You should .add() you fragment when you want to show it and .remove() it when you dont.

UPDATE:

Following you second question, when I say that you can add you fragment in your xml I mean that you can write this:

<fragment
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:id="@+id/listfragment"
    android:name="com.eadesign.yamba.TimeLineListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In your XML layout file inside your FrameLayout which is your fragment container, in this case you cant remove this fragment you can only hide it.

And just to clarify you will always have to provide some kind of layout which will be the container of your fragment/fragments.

as opposite to that you can do what your are doing in your code:

AddRemoveFragment Frag_A = new AddRemoveFragment();
transaction.add(R.id.fragment_container_1, Frag_A);
transaction.addToBackStack(null);
transaction.commit();

In this case the fragment can be removed.

UPDATE2:

Try to take this line: AddRemoveFragment Frag_A = new AddRemoveFragment(); outside of the setOnClickListener method scope. I think that your problem is the fact that you are creating a new instance of this fragment on every click of your button. In fact I would move this line FragmentManager fm1 = getSupportFragmentManager(); out side as well there is no need to get the instance of a SupportFragmentManager on each click of your button. You should do this once.

Upvotes: 3

Related Questions