Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment which is not top most in backstack is resumed

Given the application flow show in the graphic and textually described in the following.

Application flow

  1. Fragment 1 is the lowest fragment but not in the backstack by setting disallowAddToBackStack.
  2. Fragment 2 is pushed onto the stack, using fragmentTransaction.addToBackStack().
  3. A new instance of fragment 1 is pushed onto the stack.
  4. The top most fragment (fragment 1) is popped from the stack.
  5. Activity 2 becomes foreground.
  6. Activity 1 becomes foreground.

Here is the generalized method I use to handle fragments:

private void changeContainerViewTo(int containerViewId,  Fragment fragment, 
                                   Activity activity, String backStackTag) {

    if (fragmentIsAlreadyPresent(containerViewId, fragment, activity)) { return; }
    final FragmentTransaction fragmentTransaction = 
                 activity.getFragmentManager().beginTransaction();
    fragmentTransaction.replace(containerViewId, fragment);
    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    if (backStackTag == null) {
        fragmentTransaction.disallowAddToBackStack();
    } else {
        fragmentTransaction.addToBackStack(backStackTag);
    }
    fragmentTransaction.commit();
}

Problem

When activity 1 resumes in the last step the lowest instance of fragment 1 also resumes. At this point in time fragment 1 returns null on getActivity().

Question

  • Why is a fragment which is not the top most on the stack resumed?
  • If resuming the fragment is correct - how should I handle a detached fragment?
like image 707
JJD Avatar asked Oct 04 '22 11:10

JJD


1 Answers

When an Activity is not showing UI and then come to show UI, the FragmentManager associated is dying with all of your fragments and you need to restore its state.

As the documentation says:

There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state.

In your Activity onSaveInstanceState and onRestoreInstanceState, try saving you Fragment references and then restore them with something like this:

public void onSaveInstanceState(Bundle outState){
    getFragmentManager().putFragment(outState,"myfragment", myfragment);
}
public void onRetoreInstanceState(Bundle inState){
    myFragment = getFragmentManager().getFragment(inState, "myfragment");
}

Try this out and have luck! :-)

like image 135
Jorge Gil Avatar answered Oct 10 '22 02:10

Jorge Gil