Gigi
Gigi

Reputation: 359

Fragments nested do not appear after screen rotation

I have this situation,

Activity -> RestaurantsFragment -> [viewPager / FragmentPageAdapter] Two Fragments

I want to retain all the fragments after the screen rotation but what happens is that

Here is my code...

Activity.java

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

    ....

    if (savedInstanceState== null) {
        fragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMNET_RESTAURANTS);
        if(fragment==null) {
            fragment = new RestaurantsFragment();
        }
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.frame_container, fragment, (TAG_FRAGMNET_RESTAURANTS);

    }

    ....
  }

RestaurantsFragment.java

    private TabsRestaurantsAdapter tabsRestaurantsAdapter;
    private ViewPager viewPager;
    private int position;


  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Luigi-RFragment-" + id, "onCreate");

        setRetainInstance(true);


        Log.d("Luigi-RFragment-" + id, "savedInstanceState==null");
        tabsRestaurantsAdapter = new TabsRestaurantsAdapter(getChildFragmentManager());

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d("Luigi-RFragment-" + id, "onCreateView");

        View rootView = inflater.inflate(R.layout.ristoranti_fragment, container, false);

        viewPager = (ViewPager) rootView.findViewById(R.id.pager);
        viewPager.setAdapter(tabsRestaurantsAdapter);

        position = 0;
        if (savedInstanceState != null) {
            position = savedInstanceState.getInt("position");
        }

        viewPager.setCurrentItem(position);

        setHasOptionsMenu(true);

        return rootView;
    }

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

        outState.putInt("position", viewPager.getCurrentItem());
    }

TabsRestaurantsAdapter.java

public class TabsRestaurantsAdapter extends FragmentPagerAdapter {

    private String titles[] = new String[]{"I TUOI PREFERITI", "TUTTI"};
    private MenusFavTabFragment menusFavTabFragment;
    private RestaurantsAllTabFragment restaurantsAllTabFragment;

    public TabsRestaurantsAdapter(FragmentManager fm) {
        super(fm);

        menusFavTabFragment = new MenusFavTabFragment();
        restaurantsAllTabFragment = new RestaurantsAllTabFragment();
    }

    @Override
    public Fragment getItem(int index) {
        Log.d("Luigi-adapter", "getItem" + index);
        switch (index) {
            case 0:
                // Favourite Fragment
                return menusFavTabFragment;

            case 1:
                // All Restaurant
                return restaurantsAllTabFragment;

        }

        return null;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment f = (Fragment) super.instantiateItem(container, position);
        return f;
    }

    public CharSequence getPageTitle(int position) {
        return titles[position];
    }

    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return titles.length;
    }

}

Consider that when the RestaurantsFragment is reattached, the adapter (old) is setted again in the viewPager and the method of the adapter instantiateItem is invoked

The two fragments nested have nothing special

( I have also tried to recreate a new adapter each time (managing thre reuse of the old fragments) and it works but only for one rotation...but why should i recreate the adapter ? )

Why they do not appear?

Thanks.

Upvotes: 0

Views: 681

Answers (3)

Dan Nichols
Dan Nichols

Reputation: 779

This appears to be fixed in the support library version 24.

The call to onAttach() shown in the workaround was causing a NPE in the containing activity's super.onCreate() method during rotation. On a whim, I removed the onAttach() code since this NPE only occurred in the Activity/Fragment where I had implemented the solution. After removing the call to onAttach(), the NPE went away and it appears as though my code is working as expected.

See: https://code.google.com/p/android/issues/detail?id=197271

Upvotes: 0

Gigi
Gigi

Reputation: 359

Thanks Thanks Thanks @hegazy

I discovered and applyed this workaround and now it works:

retain the childFragmentManager and reassign it to the Field object

the new RestaurantsFragment.java

    //the global childFragmentManager
    private FragmentManager mRetainedChildFragmentManager;

    public void onAttach(Activity activity) {
        super.onAttach(activity);

        //To fix the bug with library v4
        if (mRetainedChildFragmentManager != null) {
            //restore the last retained child fragment manager to the new
            //created fragment
            try {
                Field childFMField = Fragment.class.getDeclaredField("mChildFragmentManager");
                childFMField.setAccessible(true);
                childFMField.set(this, mRetainedChildFragmentManager);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            mRetainedChildFragmentManager = getChildFragmentManager();
        }

    }

I hope this can help you !

Upvotes: 1

Ahmed Hegazy
Ahmed Hegazy

Reputation: 12605

This a bug in the support library v4.

For more info Nested fragments not being retained in support library.

Personally, I do the nasty thing of setting the configuration changes on my manifest to orientation and screenSize. I didn't give myself a time to think of a better way ;)

Upvotes: 1

Related Questions