Say I have 2 fragments: A and B
Fragment A is on top. Now, I add fragment B keeping A in backstack.
Now when back button is pressed, B is removed and A comes on top.
Is there any callback method in A which gets called at this point?
Note: onResume is closely bound with activity, thus it is not called. Fragment's onResume() is called only when activity's onResume() is called.
Sorry but there is no call back, as popToBackStack results to recreate fragments only in case of replace transaction and not in add.
You may want to add OnBackStackChangedListener to your fragment manager and monitor BackStackEntryCount
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() {
public void onBackStackChanged() {
Log.i(TAG, "back stack changed ");
int backCount = getSupportFragmentManager().getBackStackEntryCount();
}
}
});
Once you get this trigger, you can pass a message from activity to fragment A as described in this article Deliver a Message to a Fragment or probably have an Observer in your Fragment observe an Observable in your main Activity
onViewStateRestored() is called when fragment is shown again.
Related
I replace Fragment-A with Fragment-B, and on calling popbackstack() in Fragment-B i will redirect back to Fragment-A. So I wanted to call a method that will update the list.
One more importance difference between add and replace is: replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked. Whereas add retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused' state hence when a back button is pressed onCreateView is not called for the existing fragment(the fragment which was there before new fragment was added). In terms of fragment's life cycle events onPause, onResume, onCreateView and other life cycle events will be invoked in case of replace but they wont be invoked in case of add.
In Short for your use case, you need to use add and if you don't want the fragment views to overlap then you might replace the Fragment B view background color with a solid color instead of transparent.
When you add your fragment, you also have to add it to your fragment's backstack.
FragmentTransaction ft = getSupportFragmentManager.beginTransaction();
ft.replace(R.id.content, fragment, backStateName);
ft.addToBackStack(backStateName);
ft.commit();
(here R.id.content is your fragment container in your activity)
Then you have to override onBackPressed method in your activity that contains your fragments.
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
}
}
if you want to customize your onBackPressed then you can check for your currently visible fragment in your activity and create a callback for performing action for that particular fragment. example -
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content);
if (fragment instanceof FragmentB) {
((FragmentB) fragment).onBackPressed();
// getSupportFragmentManager().popBackStack();
}
}
now you can add getSupportFragmentManager().popBackStack(); in your Fragment's onBackPressed() method.
I have one activity containing one container that will receive 2 fragments.
Once the activity initialises i start the first fragment with:
showFragment(new FragmentA());
private void showFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment, fragment.getTag())
.addToBackStack(fragment.getTag())
.commit();
}
Then when the user clicks on FragmentA, I receive this click on Activity level and I call:
showFragment(new FragmentB());
Now when I press back button it returns to fragment A (thats correct) and when i press again back button it show empty screen (but stays in the same activity). I would like it to just close the app (since the activity has no parent).
There are a lot of posts related with Fragments and backstack, but i can't find a simple solution for this. I would like to avoid the case where I have to check if im doing back press on Fragment A or Fragment B, since i might extend the number of Fragments and I will need to maintain that method.
You are getting blank screen because when you add first fragment you are calling addToBackStack() due to which you are adding a blank screen unknowingly!
now what you can do is call the following method in onBackPressed() and your problem will be solved
public void moveBack()
{
//FM=fragment manager
if (FM != null && FM.getBackStackEntryCount() > 1)
{
FM.popBackStack();
}else {
finish();
}
}
DO NOT CALL SUPER IN ONBACKPRESSED();
just call the above method!
addToBackStack(fragment.getTag())
use it for fragment B only, not for fragment A
I think your fragment A is not popped out correctly, try to use add fragment rather replace to have proper back navigation, however You can check count of back stack using:
FragmentManager fragmentManager = getSupportFragmentManager();
int count = fragmentManager.getBackStackEntryCount();
and you can also directly call finish() in activity onBackPressed() when you want your activity to close on certain fragment count.
I have researched on stack overflow but doesn't seem to find solution.
I have one mainActivity and several frgaments, I am doing fragment transaction by
replace method and corresponding fragment added to backstack, but my problem is when I pop it out from back stack which callback is called I want to check something before pop it out from stack, onResume() method is not calling when I pop it from back stack
HELP
Just do the following:
getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
{
public void onBackStackChanged()
{
// Your logic here
}
});
This callback will be called upon each change on the back stack - even when a fragment is added. If you want to know when a fragment was removed then add the following logic
Fragment someFragment = (Fragment)getSupportFragmentManager().findFragmentById(R.id.fragmentItem);
if (someFragment == null) {
// this fragment was removed from back stack
}
Given an Activity that acts as a Home page (it never closes) that launches various fragments, how to know when the Activity is visible to the user?
From what I have observed, when I open a fragment the lifecycle for the Activity never changes, onPause() is not called. And when I close the fragment, onResume() is not called on my Activity.
Here is how I am starting my fragments, I am using this method and passing the fragment I want to launch to it.
public void addFragment(int containerId, Fragment fragment, boolean addToBackStack) {
// Check if the fragment has been added already. If so, then
// don't add the fragment.
Fragment temp = mFragmentManager.findFragmentByTag(fragment.getClass().getName());
if(temp != null && temp.isAdded()) {
return;
}
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.add(containerId, fragment, fragment.getClass().getName());
if(addToBackStack)
ft.addToBackStack(null);
ft.commit();
}
What is the methodology for indicating that my Activity is visible again? Thanks in advance!
in the oncreate method of your home activity, call
mFragmentManager.addOnBackStackChangedListener(this) ;
and then define
#Override
public void onBackStackChanged() {
int backStackCount = mFragmentManager.getBackStackEntryCount();
if(backStackCount == 0) {} //back to home screen
}
Your Activity is always Visible even if thousand Fragments are showing at the same time, for the sake of understanding Fragments are just Custom-Views, and the Fragment gives a helping hand in handling your View, so onPause() on your activity does not need to called when a Fragment dies or is born,just like inflating a View.
Just like Sir #Tim Mutton said, you need to check your BackStack to know if you are back, or you can use the ViewGroup method ViewGroup.indexOfChild(View child) - this method will an int of value getChildCount()-1 which means its on top of its fellow sibblings..
Hope it helps
how to go back from fragment to previous activity ?
I can't override this function in the fragment or there is other way, HELP!
#Override
public void onBackPressed() {
onBackPressed();
}
Somewhere in your code you likely have a FragmentTransaction where you are calling add() or replace() or show() to display the fragment. In between the display method and commit(), if you call addToBackStack(), then the operation is added to the back stack, so when you press the back button it reverses your fragment transaction.