Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which method is being called after popBackStack?

I have an activity where I am calling three fragments - each depending on each other:

A(ctivity) -> f1 (Fragment one, title {is|should}: list) -> f2 (Fragment two, title {is|should}: overview) -> f3 (Fragment three, title {is|should}: detail)

ATM I use the following method call to jump backwards:

@Override public boolean onOptionsItemSelected(MenuItem item) {     switch (item.getItemId()) {         case android.R.id.home:             FragmentManager fragmentManager = getSupportFragmentManager();             if (fragmentManager.getBackStackEntryCount()>0){                 fragmentManager.popBackStack();             }     } } 

This works fine.

I am overriding the ActionBar title in each fragment like this:

ActionBar bar = getSherlockActivity().getSupportActionBar(); bar.setTitle(R.string.title_f3); 

When navigating forward (like shown above) this works flawlessly but navigating backwards the title of the ActionBar isn´t updated:

f3 (title {is|should}: detail) -> f2 (title {is}: detail, {should}: overview) -> f1 (title {is}: detail, {should}: list)

Obviously I could just update it again when the fragment is shown. But my debugger never stops in any of the methods I´d except which would be called like onResume().

So is there actually any method being called in a previous fragment after popBackStack() ?

like image 536
OpenHaus Avatar asked Apr 04 '14 18:04

OpenHaus


2 Answers

I know this is a bit late for an answer but for anyone who navigates here this might help!

First thing is first: popBackStack()doesn't pop a fragment, it pops a fragment transaction. So the last fragment transaction is reversed upon being called. If you were displaying FragmentA currently and your transaction was:

fragmentTransaction.replace(R.id.your_layout, fragmentB); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); 

It would replace FragmentA with FragmentB, and add that transaction (not the fragment) to the back stack. If you then hit the back button, it pops the transaction off the back stack, which was "replace this FragmentA with a FragmentB". Essentially, this instruction reverses the last transaction and removes it from the stack of transactions carried out. If the original FragmentA still exists, it uses that one. If it's been destroyed, it makes a new one.

So, if the Fragment hasn't been destroyed, then recalling the fragment after using on popBackStack(), the onStart() and onResume() methods are called. If the Fragment has been destroyed previously, then the lifecycle methods will be called starting from onAttach(). It's the same as pressing the back button on Activities.

Now the important bit, what happens re fragment lifecycle when we pop off back stack? Well as said before the fragment transaction is reversed so:

Scenario 1: Your fragmentB didn't already exist before transaction. In this case the onCreate() and onAttach() methods are called during the transaction so the fragment will be destroyed and detached if you call popBackStack() and reverse the transaction (Note FragmentA probably already existed so replacing it wont destroy it as we're not undoing a fragment creation). In this case the lifecycle methods will be called starting from onAttach().

Scenario 2: Your fragmentB did already exist before transaction. In this case the fragment won't be destroyed and the next time you access it the onStart() and onResume() methods are called.

Fragment Lifecycle

This fellow here explains a few things about using popbackstack() http://vinsol.com/blog/2014/09/19/transaction-backstack-and-its-management/ and the fragment lifecycle http://vinsol.com/blog/2014/10/22/fragment-view-state-retention-a-dirty-solution/. The other related posts are worth reading too!

like image 90
Burkely91 Avatar answered Sep 25 '22 10:09

Burkely91


use addOnBackStackChangedListener method in your BaseActivity, which will be called any time backstack changes

getSupportFragmentManager().addOnBackStackChangedListener(             new FragmentManager.OnBackStackChangedListener() {                 public void onBackStackChanged() {                     FragmentManager fm = getSupportFragmentManager();                      if (fm != null) {                         int backStackCount = fm.getBackStackEntryCount();                         if (backStackCount == 0) {                             if (getSupportActionBar() != null) {                                 getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);                             }                             setToolbarTittle(R.string.app_name);                         } else {                             if (getSupportActionBar() != null) {                                 getSupportActionBar().setHomeAsUpIndicator(R.drawable.back);                             }                         }                     }                 }             }); 
like image 22
Manisha Avatar answered Sep 25 '22 10:09

Manisha