How to replace the activity's fragment from the fragment itself?

My application has a Fragment inside its Activity. I would like to programmatically replace the fragment by another one from the current fragment itself.

For example, if I click on a button inside the fragment, the fragment should be replaced with another one, but the activity should remain the same.

Is it possible? If so, how to do it?


Solution 1:

from the official docs:

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

In this example, newFragment replaces whatever fragment (if any) is currently in the layout container identified by the R.id.fragment_container ID. By calling addToBackStack(), the replaced fragment is saved to the back stack so the user can reverse the transaction and bring back the previous fragment by pressing the Back button.

The behavior you have described is exactly what fragments are designed to do. Please go through the official guide for a thorough understanding of fragments which will clear up all your questions.

http://developer.android.com/guide/components/fragments.html

Solution 2:

It's actually easy to call the activity to replace the fragment.

You need to cast getActivity():

((MyActivity) getActivity())

Then you can call methods from MyActivity, for example:

((MyActivity) getActivity()).replaceFragments(Object... params);

Of course, this assumes you have a replaceFragments() method in your activity that handles the fragment replace process.

Edit: @ismailarilik added the possible code of replaceFragments in this code with the first comment below which was written by @silva96:

The code of replaceFragments could be:

public void replaceFragments(Class fragmentClass) {
    Fragment fragment = null;
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment)
            .commit();
}

Solution 3:

Please note that fragment should NOT directly replace itself or any other fragments. Fragments should be separate entities. What fragment should do is to notify its parent activity that some event has happened. But it is, again, NOT a fragment job to decide what to do with that! It should be activity to decide to i.e. replace the fragment on phone, but to i.e. add another to existing one on tablets. So you are basically doing something wrong by design.

And, as others already mentioned, your activity should use FragmentManager ("native" or from compatibility library) to do the job (like replace() or add() or remove()):

http://developer.android.com/guide/components/fragments.html

Solution 4:

Just as Marcin said, you shouldn't have a fragment start another fragment or activity. A better way to handle this situation is by creating a callback implementation for the main activity to handle requests such as start a new fragment. Here is a great example in the android developer guide.