I need to detect backbutton pressed in Fragment.
My app start download data in Fragment, so I need to stop download (also do some operations) on back button pressed, and dont need if home button pressed. So I cant use onPause(), because its called in both cases.
I use addToBackStack(null), but I need to do some operations (stop download and ) in current fragment and then return to previous fragment.
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack(null)
.commit();
When you are done with the things you want to do in the fragment you could use something like this to remove the current fragment. If last fragment was added to the stack (as you mentioned) then removing current fragment will automatically display last fragment.
this.getActivity().getSupportFragmentManager().beginTransaction()
.remove(this).commit();
or
this.getActivity().getFragmentManager().beginTransaction()
.remove(this).commit();
Look at this link
On yout activity you can overide onBackPressed() et then call popBackStack
Related
The project is multiple-fragment project. Launch application to start BaseActivity, which all fragments are attached into it.
Issue:
Fragment A is the first fragment and is launched very well.
Fragment B is trigged by clicking button of Fragment A, also launched very well.
During from B back to A, the problem occurs. Nothing to display, only background, the BaseActivity.
All fragments use the api "replace" to display, although this API may produce performance problems, please ignore it firstly.
I have tried many methods, but nothing works.
The launched fragment method shows below:
public void navigateToFragment(Fragment fragment, boolean isClear){
if(isClear){
getSupportFragmentManager()
.popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(R.id.container,fragment)
.commit()
}
As I know, popBackStack and replace, commit can lead to one fragment is launched twice, but why no display after replace whatever I replace it?
try use add instead of replace
getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.add(R.id.container,fragment)
.commit()
My app has 3 UI levels, each level has its own fragment, A -> B -> C.
I wish to optionally allow my app user to navigate straight to the top level fragment i.e. from C -> A without invoking B.
i.e., I still want to allow the user to go from C->B if they press the back button, but in the C fragment, I have a "Home" button, which takes them directly to A. This is the operation where I want to flush the backstack.
Additionally, I want the user to be able to go from B->A using the back button, hence I'm adding A and B both to the backstack.
I have tried the options from this SO post but in each case, onCreateView gets invoked for each fragment, even if I use fm_.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Also checked this thread, it seems to recommend using popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
Can anyone please suggest a way to pop the entire backstack without having the onCreateView called on popped fragments?
Dont add backStack line for going from fragment B->C
while going from A->B use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment) // LL_Fragment is container
.addToBackStack(null)
.commit();
while going B->C use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment)
.commit();
dont add line .addtobackstack(null)
This worked for me
i estimate you're using replace fragment.
try to use begintransaction.hide / show to manage many fragment inside 1 activity if you don want to popback
//on Activity
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(containerId, new FragmentA(), fragmentA.getClass().getSimpleName());
fragmentTransaction.commit();
//inside fragment A to jump fragment without PopBackStack
getFragmentManager().beginTransaction().hide(this).commit();
getFragmentManager().beginTransaction().show(new FragmentB()).commit();
This is working for me when needing to clear the back stack for tab switches in BottomNavigationView
public void clearBackStack() {
int backStackEntryCount = mFragmentActivity
.getSupportFragmentManager()
.getBackStackEntryCount();
for (int i = 0; i < backStackEntryCount; i++) {
mFragmentActivity.getSupportFragmentManager().popBackStack();
}
}
Having a flow to add fragment and later replace() fragment. All fragment are dynamically added, but not all call addToBackStack().
getSupportFragmentManager().beginTransaction()
.add(R.id.frgment_holder, frgmtA, frgmtA.NAME)
.commit();
and in somewhere it could add another, like:
getSupportFragmentManager().beginTransaction()
.replace(R.id.frgment_holder, frgmtB)
.addToBackStack(frgmtB.NAME)
.commit();
the replace() with the frgmtB will remove the frgmtA from the container R.id.frgment_holder.
if press back button at this state, it will pop the frgmtB. But will it recreate the frgmtA even if it did not call addToBackStack() when did the adding?
if in the flow of adding fragment into same container with a serials mixed add() and replace() calls, and someone call addToBackStack() but someone do not, how would the back button behavior?
EDIT:
after
getSupportFragmentManager().beginTransaction()
.replace(R.id.frgment_holder, frgmtB)
.addToBackStack(frgmtB.NAME)
.commit();
will the
getSupportFragmentManager().findFragmentByTag(frgmtA.NAME);
still find the the frgmtA? what if when add frgmtA also called addToBackStack();
The doc says "This first searches through fragments that are currently added to the manager's activity; if no such fragment is found, then all fragments currently on the back stack are searched."
The case would be
adding frgmtA; not call add to stack; UI state changed here;
(what if the frgmtA is not dynamically added by add(), but sepcified in layout file with class="frgmtA"?).
replace() with frgmtB; addToStack();
replace() with frgmtC; addToStack();
then if the stackTop is frgmtC, would like the back button press to bring back the first frgmtA with its last UI state.
1.
.add(R.id.frgment_holder, frgmtA, frgmtA.NAME)
.commit();
.replace(R.id.frgment_holder, frgmtB, frgmtB.NAME)
.addToBackStack(frgmtB.NAME)
.commit();`
the replace will remove the frgmtA from the the holder and its onDestroyView will be called (but since it is referenced in the backstack’s transaction data, frgmtA is NOT destroyed). And the frgmtB will be added to the holder.
Since the frgmtA is not destroyed, the
getSupportFragmentManager().findFragmentByTag(frgmtA.NAME);
will find it.
after then, press on back button, it will pop the top transaction from the backStack, then reversing the transaction. i.e. remove frgmtB from the holder and add frgmtA back to the holder. Since there is no more reference to frgmtB its onDestroy is called.
2.
in the case of
add frgmtA;
replace() with frgmtB; addToStack();
replace() with frgmtC; addToStack();
If want to back press to jump to frgmtA, need to override onBackPressed(), in it
do
popBackStack(frgmtB.NAME, POP_BACK_STACK_INCLUSIVE),
which will toss out the transaction in the stack above stack entry named frgmtB.NAME and do reverse the transaction on it, which will add back the frgmtA in the holder.
Unless you interfere with the Back button logic using onBackPressed() or addOnBackStackChangedListener(), things are straight forward
if you add a fragment through addToBackStack(), it will be removed when Back is tapped
if there are no other fragments left in the back stack, app will be closed
try this anyone line as your demand
its 4 differnt lines code you have checked
getActivity().getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getActivity().getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.framelayout, fragment);
transaction.addToBackStack(null);
getActivity().getSupportFragmentManager().popBackStack();
My Application has one Activity with a layout (FrameLayout) for many fragments.
At the start of the Application it displays a list of Places (PlacesFragment).
When a Place is clicked, a Fragment that displays a list of cams (CamFragment) is added. Inside this fragment there is also a button "info".
When the user press the "info" button a new fragment (InfoPlaceFragment) that displays information about the place, is added.
Here is a graphical explanation:
I want to be able to go back to "CamFragment(B)" from "InfoPlaceFragment(C)", and to go back to "PlacesFragment(A)" from "CamFragment(B)".
One Question:
1) Is it possible to realize this or an alternative solution is better?
------- EDIT -------
SOLUTION:
In the "MainActivity.java":
onPlaceParse() // This method is called when the data from the server is received:
// Here I create the "PlaceFragment"
fManager = getSupportFragmentManager();
fragmentPlaces = new PlacesFragment();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentPlaces)
.commit();
onResortSelected // This method is called when the resort is selected
fragmentCams = new CamsFragment();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentCams)
.addToBackStack(null)
.commit();
onButtonInfoSelected // This method is called when the btn info is selected
fragmentInfo = new InfoResortFragment();
fManager = getSupportFragmentManager();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentInfo, "Info")
.addToBackStack(null)
.commit();
When you press the back button, if you are in the "Info Fragment" it returns to "PlaceFragment" and if you are in the "CamsFragment" it returns to "PlacesFragment".
This is possible, you need to call addToBackStack(null) in the fragment transactions.
Reference: Providing Proper Back Navigation
When you create your FragmentTransaction that will add/remove/replace (or whatever pattern you are using) the Fragments, just make sure to call addToBackStack(). Then, when the user presses the back button, the system will automatically cycle back through the entries added to the back stack, in reverse order from how they were originally added. No additional work is required on your part! :)
I have Fragment1. On them, i pressed button and start DialogFramgent. On DialogFragment i pressed button and start Fragment2. When i pressed back, i am return to Fragment1, but not to DialogFragmnet
You can add the fragment to the backstack. A call addToBackStack() should solve the problem. Straight from the documentation: "This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button". See for details:
http://developer.android.com/guide/components/fragments.html
Jasper
A great feature about using fragments in your activity is the ability to add, remove, replace, and perform other actions with them, in response to user interaction. Each set of changes that you commit to the activity is called a transaction and you can perform one using APIs in FragmentTransaction. You can also save each transaction to a back stack managed by the activity, allowing the user to navigate backward through the fragment changes (similar to navigating backward through activities).
You can acquire an instance of FragmentTransaction from the FragmentManager like this:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for a given transaction using methods such as add(), remove(), and replace(). Then, to apply the transaction to the activity, you must call commit().
Before you call commit(), however, you might want to call addToBackStack(), in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.