Munez NS
Munez NS

Reputation: 1011

Added Fragment is not removed and causing App crash

Adding fragment works ok, but removing it crashes app. I thought removing will be straight forward but Im still a beginner so I must missing something. Can you take a look?

public class MainActivity extends Activity implements OnClickListener {

    Button addFragment, closeFragment;
    android.app.FragmentManager fragmentManager = getFragmentManager();
    android.app.FragmentTransaction transaction = fragmentManager
            .beginTransaction();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initialize();
    }

    private void initialize() {
        addFragment = (Button) findViewById(R.id.bAddF);
        closeFragment = (Button) findViewById(R.id.bCloseF);
        addFragment
                .setOnClickListener((android.view.View.OnClickListener) this);
        closeFragment
                .setOnClickListener((android.view.View.OnClickListener) this);
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
            //Instantiate fragment from ExampleFragment class
             ExampleFragment fragment = new ExampleFragment();
             switch(arg0.getId()){      
                 case R.id.bAddF:
                      transaction.add(R.id.fragment_holder, fragment).commit();
                 break;
                 case R.id.bCloseF:
                      transaction.remove(fragment).commit();
                 break;
             }
    }

}

Upvotes: 0

Views: 700

Answers (1)

Philipp Jahoda
Philipp Jahoda

Reputation: 51411

Your app crashes because you are saving the FragmentTransaction as a member variable. But FragmentTransactions cannot be reused. Furthermore, you are creating a new Fragment everytime, which means that the currently added Fragment will not be removed when clicking the remove Button.

Do it this way:

    private ExampleFragment mFragment;

    @Override
    public void onClick(View v) {

          //Instantiate fragment from ExampleFragment class
          if(mFragment == null) mFragment = new ExampleFragment();

          switch(v.getId()){      
              case R.id.bAddF:
                 getFragmentManager().beginTransaction().add(R.id.fragment_holder, mFragment, "tag").commit();
                 break;
              case R.id.bCloseF:
                 getFragmentManager().beginTransaction().remove(mFragment).commit();
                 break;
          }
     }

Create a new FragmentTransaction for each add() or remove() procedure.

As an alternative for keeping your ExampleFragment as a member variable, you can use FragmentManager.findFragmentByTag("tag") to get the currently added fragment.

Alternative way:

    @Override
    public void onClick(View v) {

          switch(v.getId()){      
              case R.id.bAddF:
                 getFragmentManager().beginTransaction().add(R.id.fragment_holder, new ExampleFragment(), "tag").commit();
                 break;
              case R.id.bCloseF:
                 Fragment frag = getFragmentManager().findFragmentByTag("tag");
                 getFragmentManager().beginTransaction().remove(frag).commit();
                 break;
          }
     }

Upvotes: 1

Related Questions