Preventing the same fragment from stacking more than once (addToBackStack)

I have an Activity with three fragments that call them A , B and C. Fragment A is called in Activity onCreate() .

 FragmentA fragA = new FragmentA(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.activity2_layout, fragA, "A"); transaction.commit(); 

And it is replaced with Fragment B or C when some buttons are pressed, and FragmentTransaction calls addToBackStack() .

 FragmentB fragB = new FragmentB(); //or C FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.activity2_layout, fragB, "B"); //or C transaction.addToBackStack("B"); //or C transaction.commit(); 

But let's say I call Fragment B three times in a row, how can I prevent it from laying on itself? And at the same time, I want it to be possible: B , called> C , called> B , but when I try to go back I want to open B only once ( C < B ) instead of ( B < C < B ). So basically removing the first backStack with the new one.

+5
source share
2 answers

From How to resume a fragment from BackStack, if it exists , which may be very similar to your request.

There is a way to put a back stack based on the name of the transaction or identifier provided by the commit (for example, using the fragment class name as Thijs already mentioned):

 String backStateName = fragment.getClass().getName(); 

Adding to backstack:

 FragmentTransaction ft = manager.beginTransaction(); ft.replace(R.id.content_frame, fragment); ft.addToBackStack(backStateName); ft.commit(); 

When you press:

 getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

So, before replacing the fragment, we can check the existence in the backstack, for example:

 boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0); if (!fragmentPopped){ //fragment not in back stack, create it. ... ... ft.addToBackStack(backStateName); ft.commit(); } 

Please check the question above and the accepted answer for a more detailed explanation.

+8
source

I solved one of your questions, namely how can I prevent it from stacking on to it self? , in one of my own projects some time ago. This was the exact code I used there:

 public void setContent(@NonNull Fragment fragment, boolean addToBackStack) { Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content); if (current == null || !current.getClass().equals(fragment.getClass())) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); if (addToBackStack) { transaction.addToBackStack(null).add(R.id.main_content, fragment).commit(); } else { transaction.replace(R.id.main_content, fragment).commit(); } } } 

What this code does is check which class the current fragment shows and compare it with the fragment you want to replace. If they are the same, it does nothing. This code can be tailored to suit your needs.

 Fragment newFragment = new FragmentB(); //OR FragmentC Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout); if (!current.getClass().equals(newFragment.getClass())) { //POP BACKSTACK HERE LIKE EXPLAINED BELOW FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); final String tag = newFragment.getClass().getSimpleName(); transaction.addToBackStack(tag); transaction.add(R.id.activity2_layout, newFragment, tag); transaction.commit(); } else { //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME } 

Having made sure that only one fragment of a certain type is present at a time, perhaps one could have achieved by placing the stack back before the first appearance of the same fragment. I have not written any code for this, but it is not too difficult to implement this function. If you cannot figure it out on your own, let me know and I will try to write you an example :)

+1
source

Source: https://habr.com/ru/post/1236163/


All Articles