androidandroid-fragmentsscreen-rotationonrestoreinstancestate

Android rotation: Why fragment not restored by TAG?


I have an activity called MainActivity with a fragment inside called 'HomeFragment'. I want to restore fragment after screen rotation, however something seems missing. I followed below process:

  1. save fragment by using getSupportFragmentManager().putFragment(...) during onSaveInstanceState
  2. try to restore fragment by fragmentManager.findFragmentByTag during onCreate (after checking that bundle is not null)

However findFragmentByTag returns null.

Here is code snippets inside MainActivity:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set up the action bar to show a dropdown list.
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        setupNavigationSpinner(actionBar);
        FragmentManager fragmentManager = getSupportFragmentManager();

        if (savedInstanceState != null) {

            if (fragmentManager.findFragmentByTag("frag") != null) { 
                //  findFragmentByTag always return null
                homeFragment = (HomeFragment) fragmentManager
                        .findFragmentByTag(HomeFragment.ARG_ITEM_ID);
                contentFragment = homeFragment;
            }else{
                homeFragment = new HomeFragment();
                switchContent(homeFragment, HomeFragment.ARG_ITEM_ID);
            }
        } else {
            homeFragment = new HomeFragment();
            switchContent(homeFragment, HomeFragment.ARG_ITEM_ID);
        }

}


@Override
public void onSaveInstanceState(Bundle outState) {
    getSupportFragmentManager().putFragment(outState, "frag",homeFragment );
}

public void switchContent(Fragment fragment, String tag) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    while (fragmentManager.popBackStackImmediate())
        ;

    if (fragment != null) {
        FragmentTransaction transaction = fragmentManager
                .beginTransaction();
        transaction.replace(R.id.content_frame, fragment, tag);
        // Only ArticlDetailFragment is added to the back stack.
        if (!(fragment instanceof Fragment)) {
            transaction.addToBackStack(tag);
        }
        transaction.commit();
        contentFragment = fragment;
    }
}

Solution

  • There is no reason to call

    getSupportFragmentManager().putFragment(outState, "frag",homeFragment );
    

    A Fragment state will automatically be restored. The problem is that you're not calling the super of your onSaveInstanceState. It should simply look like this:

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }
    

    Also, you're setting the tag as HomeFragment.ARG_ITEM_ID then looking for "frag". Does HomeFragment.ARG_ITEM_ID == "frag"?