Unable to change fragment container id

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.

+4
source share
2 answers

I have found a solution. For portrait and landscape mode, I use ViewPager, but I override the page adapter method:

public float getPageWidth (int position)

In the normal state, this method returns 1.0f, and the ViewPager displays one page, but when the method returns 0.5f, two pages. In portrait mode, set PAGE_WIDTH_FULL_SCREEN and in the landscape PAGE_WIDTH_HALF_SCREEN when you create the adapter in action. Sample code with overridden public methods below:

 public class ViewPagerAdapter extends FragmentPagerAdapter { public static final float PAGE_WIDTH_FULL_SCREEN = 1.0f; public static final float PAGE_WIDTH_HALF_SCREEN = 0.5f; private FragmentManager fragmentManager; private ArrayList<Fragment> fragments; private float pageWidth = PAGE_WIDTH_FULL_SCREEN; public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments) { super(fm); this.fragmentManager = fm; this.fragments = fragments; } public void setPageWidth(float pageWidth) { this.pageWidth = pageWidth; } @Override public float getPageWidth(int position) { return pageWidth; } @Override public Fragment getItem(int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } } 
+1
source

First you need to delete it.

 if (null != pager) { pager.setAdapter(new PagerAdapter(getFragmentManager(), mUpdater)); } else { FragmentManager fm = getFragmentManager(); fm.beginTransaction().remove(mSummaryFragment).add(R.id.summary_container, mSummaryFragment).commit(); fm.beginTransaction().remove(mDetailsFragment).add(R.id.details_container, mDetailsFragment).commit(); } 
-3
source

Source: https://habr.com/ru/post/1496491/


All Articles