146

I have a fragment inside a group activity and I want to replace it with another fragment:

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

It works fine when it is done as a seperate project without using activity group, every thing works fine in log cat as control goes inside getview(), but no view is visible, not even any exception arises, I want the book detail fragment to be replaced by section detail fragment.

Xml of book detail fragment has id book_description_fragment and xml for section description fragment has id section_description_fragment.

The above code is in onClick method of an item, I want that when user taps on an item in horizontal scroll view, then the fragment changes.

UmarZaii
  • 1,355
  • 1
  • 17
  • 26
Lion Heart
  • 1,471
  • 2
  • 10
  • 5

13 Answers13

266

Fragments that are hard coded in XML, cannot be replaced. If you need to replace a fragment with another, you should have added them dynamically, first of all.

Note: R.id.fragment_container is a layout or container of your choice in the activity you are bringing the fragment to.

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

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

// Commit the transaction
transaction.commit();
William Reed
  • 1,717
  • 1
  • 17
  • 30
C--
  • 16,393
  • 6
  • 53
  • 60
  • 11
    what is the R.id.fragment_container in this case? – Guy Jul 17 '14 at 14:18
  • 4
    @Guy, It can be any layout you wish to load the fragment into. – C-- Jul 18 '14 at 05:17
  • can I skip addToBackStack if I dont need the back button behavior for certain fragment? – Divyansh Goenka Apr 10 '15 at 07:12
  • 1
    what should be the name of fragment in xml file? I want to add fragment dynamically and don't want any static fragment. – Rajat Mehra Jun 30 '15 at 09:14
  • 1
    @RajatMehra If you want to add fragments dynamically, you don't have to specify the fragment inside the XML at all. You can use a container view. Please read the answer again. – C-- Jul 02 '15 at 03:56
  • 1
    "Fragments that are hard coded in XML, cannot be replaced." - i agree with Jomia: this is the information that i couldn't find elsewhere when trying to find out why my layout didn't get replaced. Thanks for this! – zreptil Aug 31 '15 at 13:08
  • In the case of that fragment's name is fixed at xml file, it doesn't work. – LKM Oct 12 '15 at 09:06
  • Why android documents has no such information and people have to work it out trial and error ? – Ahmed Dec 20 '15 at 12:57
  • 4
    @Ahmed The reason is that, by architecture, the system replaces every tag with the view (group) provided by the corresponding fragments' `onCreateView()`. Thus, as you can assume, any reference to the fragment is actually lost at the view level. So, you basically cannot replace a fragment, but rather you can manually remove the views now present in the container and put a fragment there instead if required. – C-- Dec 21 '15 at 06:40
  • the fragment_container can be a constraint layout of original? – luke cross Apr 30 '20 at 12:56
  • this is not an answer to the main question! Questions asks how to replace a fragment with another one? and you are replacing a view (place holder for the fragment) with a fragment! – Araz Mar 13 '22 at 18:55
37

Please see this Question

You can only replace a "dynamically added fragment".

So, if you want to add a dynamic fragment, see this example.

Community
  • 1
  • 1
Sana
  • 9,895
  • 15
  • 59
  • 87
8

I've made a gist with THE perfect method to manage fragment replacement and lifecycle.

It only replace the current fragment by a new one, if it's not the same and if it's not in backstack (in this case it will pop it).

It contain several option as if you want the fragment to be saved in backstack.

=> See Gist here

Using this and a single Activity, you may want to add this to your activity:

@Override
public void onBackPressed() {
    int fragments = getSupportFragmentManager().getBackStackEntryCount();
    if (fragments == 1) {
            finish();
            return;
    }

    super.onBackPressed();
}
Hugo Gresse
  • 17,195
  • 9
  • 77
  • 119
  • 1
    @RémiP the link is working as expected. You can check this one that may be better IMO https://github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/gresse/hugo/anecdote/util/FragmentStackManager.java#L42 – Hugo Gresse Jul 28 '17 at 07:10
8

Use the below code in android.support.v4

FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();
Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
Sachin Suthar
  • 692
  • 10
  • 28
4

Use ViewPager. It's work for me.

final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager); 
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        viewPager.setCurrentItem(1);
    }
});
Nikolay
  • 49
  • 2
2

hope you are doing well.when I started work with Android Fragments then I was also having the same problem then I read about 1- How to switch fragment with other. 2- How to add fragment if Fragment container does not have any fragment.

then after some R&D, I created a function which helps me in many Projects till now and I am still using this simple function.

public void switchFragment(BaseFragment baseFragment) {
    try {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
            ft.add(R.id.home_frame, baseFragment);
        } else {
            ft.replace(R.id.home_frame, baseFragment);
        }
        ft.addToBackStack(null);
        ft.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

enjoy your code time :)

John smith
  • 1,781
  • 17
  • 27
1

you can use simple code its work for transaction

Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit(); 
Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
1

You Can Use This code

((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();

or You Can This Use Code

YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);

        if (fragments==null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
        }
Diako Hasani
  • 1,384
  • 13
  • 14
1

I change fragment dynamically in single line code
It is work in any SDK version and androidx
I use navigation as BottomNavigationView

    BottomNavigationView btn_nav;
    FragmentFirst fragmentFirst;
    FragmentSecond fragmentSecond;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        fragmentFirst = new FragmentFirst();
        fragmentSecond = new FragmentSecond ();
        changeFragment(fragmentFirst); // at first time load the fragmentFirst
        btn_nav = findViewById(R.id.bottomNav);
        btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch(menuItem.getItemId()){
                    case R.id.menu_first_frag:
                        changeFragment(fragmentFirst); // change fragmentFirst
                        break;
                    case R.id.menu_second_frag:
                        changeFragment(fragmentSecond); // change fragmentSecond
                        break;
                        default:
                            Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }
public void changeFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
    }
Mahdi Safari
  • 298
  • 3
  • 12
0

In kotlin you can do:

// instantiate the new fragment
val fragment: Fragment = ExampleFragment()

val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()
Nicola Gallazzi
  • 7,897
  • 6
  • 45
  • 64
0

This will work if you're trying to change the fragment from another fragment.

Objects.requireNonNull(getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_fragment_container,new NewFragment())

NOTE As stated in the above answers, You need to have dynamic fragments.

emkarachchi
  • 750
  • 1
  • 7
  • 18
0

You can use fragment-ktx

// If you are in fragmet
childFragmentManager.beginTransaction()

// or if you are in activiry
supportFragmentManager.beginTransaction()

// Create and commit a new transaction
supportFragmentManager.commit {
  setReorderingAllowed(true)
  // Replace whatever is in the fragment_container view with this fragment
  replace<ExampleFragment>(R.id.fragment_container)
}
Saeed Darvish
  • 621
  • 6
  • 29
0

To replace a fragment with another one do this, Note that R.id.fragment comes from the id that you give to the first tag of the fragment in the XML.

barAudioPlaying.setOnClickListener(view -> {
                getActivity().getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.fragment,new HomeFragment())
                        .commit();
Zero
  • 51
  • 5