Keep Android Fragments in Backstack - android

I'm working on android fragments and i am unable to keep the fragments in backstack i-e when i press back button it pushes me out of the Activity which starts fragments, i want to go back to previous fragment on backpress.
So far i have tried this but i am unable to keep the fragments in backstack.
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.mainContainer, searchResultsFragment)
.addToBackStack(null)
.commit();

before you call commit() to commit transaction, you should add fragment to backstack addToBackStack(null) as you did in your provided code
then override onBackPressed() to pop fragment from stack
the issue you facing , you make your transaction with FragmentManager
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.mainContainer, searchResultsFragment)
.addToBackStack(null)
.commit();
but you in onBackPressed() you using SupportFragmentManager
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0 ) {
getSupportFragmentManager().popBackStack();
}
}
to fix your issue , you must know what you match your fragment type (in your case searchResultsFragment) I mean if its extend Fragment or support Fragment
in case you extend fragment support
import android.support.v4.app.Fragment;
you should use getSupportFragmentManager() in both transaction and onBackPressed
in case you use fragment
import android.app.Fragment;
you should use getFragmentManager() in both transaction and onBackPressed

You have to overwrite onBackPressed in your activity. It is not enough only adding the fragment to back stack.
#Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
if(fragmentManager.getBackStackEntryCount() != 0) {
fragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}

I just remove this line:
.addToBackStack(null)
And works for me.

Related

Handle OnBackPress from Fragment

I have 3 fragments Fragment1, Fragment2 and Fragment3 and navigation is like
Fragment1->Fragment2->Fragment3
But on back press From Fragment3 go back to Fragment2 after completing some task like from Fragment2. And from Fragment1 finish this activity.
what will be the best method to do this task.
As per your question just you have to add addToBackStack() method before commit() transaction.
for example:
FirstFragment firstFragment = new FirstFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.article_fragment, firstFragment)
.addToBackStack(null).commit();
Add second and third fragment same as above manner and just add code in onBackPressed() Override method.
for example:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Please follow the process.
1. When you add fragment add below code to your code
fragmentTransaction.addToBackStack(null);
Then back button handle from the activity.
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount()>0){
getFragmentManager().popBackStack();
}else {
super.onBackPressed();
} }
It will be working perfectly. Happy coding.
There is no need to handle OnBackPress inside Fragment. When you performing Fragment transaction, you can put your fragment to BackStack:
When there are FragmentTransaction objects on the back stack and the user presses the Back button, the FragmentManager pops the most recent transaction off the back stack and performs the reverse action (such as removing a fragment if the transaction added it).
More details you can get from this article.

popBackStackImmediate not showing fragment when the current fragment transaction is not added in the backstack

Popbackstack is working fine when all the fragments in the sequence are added in the backstack but isnt working when one of the transactions is not added in the backstack.
Here is my navigation:
1.Replace fragment to load home fragment. This transaction not added to backstack.
Replace fragment to load login fragment. This transaction is added to backstack.
3.Replace fragment to load loggedin fragment. This transaction is not added to backstack.
Now, when i press back button once nothing happens. Whereas ideally it should go to the home fragment from logged in fragment.
Here is my onbackpressed method in main activity:
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount()>0)
{
FragmentManager.BackStackEntry backStackEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1);
String str = backStackEntry.getName();
FragmentManager fm=getSupportFragmentManager();
//getSupportFragmentManager().popBackStackImmediate();
fm.popBackStack(str, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
else {
super.onBackPressed();
}
}
popBackstack only 'pop' what is in the backstack.
Since you haven't add the transaction when replacing the LoginFragment by the LoggedInFragment when you press back:
the LoggedInFragment remains,
the LogInFragment is popped
the HomeFragment is displayed
But because the LoggedInFragment as been added after the HomeFragment, the HomeFragment is displayed underneath it. So you can't see it as hidden by the LoggedInFragment.
One solution is to add the transaction to the back stack when you replace the LogInFragment by the LoggedInFragment.
Then in onBackPressed you test if the current fragment is the LoggedInFragment. If it's the case you pop the back stack up to HomeFragment (not inclusive). Like that both LoggedInFragment and LogInFragment will be pop.
EDIT
#Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentById(R.id.my_fragment_container);
// If there is something in the back stack AND the current fragment is the LoggedInFragment
if (manager.getBackStackEntryCount() > 0
&& fragment instanceof LoggedInFragment) {
manager.popBackStack(HomeFragment.class.getSimpleName(), 0);
} else {
super.onBackPressed();
}
}
In order to retrieve the HomeFragment by name you need to tag your transaction when you replace the current fragment by the HomeFragment. Generally I tag all transactions with the fragment's class simple name so like that I can retried any fragment:
transaction.replace(R.id.my_fragment_container, fragment, fragment.getClass().getSimpleName());
Eselfar's explanation of the problem is correct, but the code he provided wasn't generic enough for me.
I (hopefully) resolved this issue in a general case by the following code:
#Override
public void onBackPressed() {
Fragment currentFragment = getCurrentFragment();
if (mFragmentManager.getBackStackEntryCount() > 0) {
// In a normal world, just popping back stack would be sufficient, but since android
// is not normal, a call to popBackStack can leave the popped fragment on screen.
// Therefore, we start with manual removal of the current fragment.
removeCurrentFragment();
mFragmentManager.popBackStack();
} else {
super.onBackPressed();
}
}
private Fragment getCurrentFragment() {
return mFragmentManager.findFragmentById(getContentFrameId());
}
private void removeCurrentFragment() {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.remove(getCurrentFragment());
ft.commit();
// not sure it is needed; will keep it as a reminder to myself if there will be problems
// mFragmentManager.executePendingTransactions();
}

How to go back to last activity from fragment?

How is it possible to go back to the last Activity one has been in from a Fragment? Let's assume we've Activity A and Fragment A. I launch Fragment A from Activity A, and now I want to go back to Fragment A. When I press on the back button on my phone it closes the app.
I launch the fragment by using the FragmentManager:
Fragment fragment = new Kontakt();
getFragmentManager().beginTransaction()
.add(R.id.kontaktfrag, fragment)
.commit();
Is the solution; popBackStackImmediate() or addToBackStack() ?
Firstly try addToBackStack when adding your fragment.
then you need to override your onBackPressed function of your activity, for example:
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
} else {
super.onBackPressed();
}
}
I tried myself and it worked.
try adding
getFragmentManager()
.beginTransaction()
.addToBackStack("")
.commit();
or just add .addToBackStack("") before .commit();
here is the code in your case,
Fragment fragment = new Kontakt();
getFragmentManager().beginTransaction()
.add(R.id.kontaktfrag, fragment)
.addToBackStack("")
.commit();

fragment backstack replace issue

I have fragments in backstack which is added by using addtobackstack function.
When i add a fragment without not using addtobackstack function and then press back button, the backstack is go back to wrong fragment.
For example:
Fragment A is replaced by using addtobackstack
Fragment B is replaced by using addtobackstack
Fragment C is replaced without not using addtobackstack
Fragment D is replaced by using addtobackstack
When i was in Fragment D and press the back button, i am going to Fragment A. But i must go to Fragment B.
How can i fix it?
Thanks,
Put this code in Activity then try.
Fragment is followed with Activity so when you use fragment with addToBackStack() with tag or passing null will add fragment in stack with help of FragmentManager.
Not necessary to addToBackStack(). comment this code or pass null
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager .beginTransaction();
fragmentTransaction .replace(R.id.fragment_container, YouNextFragment);
fragmentTransaction .addToBackStack(null);
fragmentTransaction .commit();
When you press back button in Activity FragmentManager automatically popUp latest added fragment.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (getFragmentManager().getBackStackEntryCount() ==0) {
finish();
}else{
getFragmentManager().popBackStack();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}

Android: fragments in Activity: after popBackStack() the number of present fragments stills the same

In my Activity, I add the first Fragment (myFragmentA) in onCreate() method:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
.add(containerViewId, myFragmentA, fragmentTag)
.addToBackStack(null)
.commit();
In this first fragment, when I click on a Button, I add a new fragment (myFragmentB):
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
.replace(containerViewId, myFragmentB, fragmentTag)
.addToBackStack(null)
.commit();
All is great to this point.
When I catch back pressed from Activity:
#Override
public void onBackPressed() {
// >>> Just to prevent to keep the first fragment !!
if (getSupportFragmentManager().getFragments().size() > 1) {
getSupportFragmentManager().popBackStack();
}
}
Back pressed from myFragmentB > myFragmentA : OK
Back pressed from myFragmentA (just to verify there is no popback) : FAILED. myFragmentA is removed too! And I want to keep it always. I don't know why getSupportFragmentManager().getFragments().size() is equal 2!
Thanks for your helps guys!
If i correctly understood.
You want to use
getBackStackEntryCount()
instead of
getFragments().size()
Take a look at the docs: http://developer.android.com/reference/android/support/v4/app/FragmentManager.html
You see, your container activity gets added to the back stack by default. In your code you have written addToBackStack(null) for both the fragments, this will add your fragments to the back stack over and above your activity which gets added to the back stack by default. This explains why you are seeing size 2, one may be your activity and the other your fragment.

Categories

Resources