I have a working application that I am trying to optimize for use on a tablet by inflating a different layout in accordance with the Android documentation.
The problem is that when in portrait orientation my view is populated by the ViewPager, and my two important fragments and their adapter data in it. When in landscape orientation, the view is filled with the same two fragments, but side by side in the same layout, and not in ViewPager. I save the fragments in onSaveInstanceState and get them again as follows:
@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mSummaryFragment != null) { getFragmentManager().putFragment(outState, TAG_SUMMARY, mSummaryFragment); } if (mDetailsFragment != null) { getFragmentManager().putFragment(outState, TAG_DETAILS, mDetailsFragment); } }
Getting in onCreate ...
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { mSummaryFragment = (SummaryFragment) getFragmentManager().getFragment(savedInstanceState, TAG_SUMMARY); mDetailsFragment = (DetailsFragment) getFragmentManager().getFragment(savedInstanceState, TAG_DETAILS); } else { mSummaryFragment = new SummaryFragment(); mDetailsFragment = new DetailsFragment(); } }
I must mention that these fragments are nested because my main activity is actually a fragment. Starting from 4.2, I believe that this should not be a problem, but I am not 100% savvy on the life cycle. My view is filled as follows:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { setHasOptionsMenu(true); View result = inflater.inflate(R.layout.main, container, false); ViewPager pager = (ViewPager) result.findViewById(R.id.viewpager); if (null != pager) { pager.setAdapter(new PagerAdapter(getFragmentManager(), mUpdater)); } else { FragmentManager fm = getFragmentManager(); fm.beginTransaction().add(R.id.summary_container, mSummaryFragment).commit(); fm.beginTransaction().add(R.id.details_container, mDetailsFragment).commit(); } if (savedInstanceState == null) { Refresh(0,0); } return (result); }
The getItem PagerAdapter method is as follows:
@Override public Fragment getItem(int position) { switch (position) { case 0: return mSummaryFragment; case 1: return mDetailsFragment; } return null; }
Everything works fine at the first start, but when the orientation changes, I get this error in logcat regardless of how the orientation changes (portrait β landscape or vice versa):
java.lang.IllegalStateException: cannot change the container identifier of the fragment SummaryFragment {40dd1800 # 1 id = 0x7f0b004a android: switcher: 2131427400: 0}: was 2131427402 now 2131427400
I'm not quite sure if this is the best way to do what I want - however, saving fragments in a bundle and extracting them was a trick I found in the source code of Google IO 2013, so I hope that it is at least partially on the right.