У меня есть рабочее приложение, которое я пытаюсь оптимизировать для использования на планшетах, раздувая другой макет в соответствии с документацией Android.
У меня проблема в том, что в портретной ориентации мое представление заполняется ViewPager, а также двумя важными фрагментами и их данными в его адаптере. В альбомной ориентации представление заполняется теми же двумя фрагментами, но рядом в одном макете, а не в ViewPager. Я сохраняю фрагменты в onSaveInstanceState и снова извлекаю их следующим образом:
@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);
}
}
Получение в 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();
}
}
Я должен упомянуть, что эти фрагменты являются вложенными, потому что моя основная деятельность на самом деле является самим фрагментом. Начиная с 4.2, я считаю, что это не должно быть проблемой, но я не на 100% разбираюсь в жизненном цикле. Мое представление заполняется следующим образом:
@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);
}
Метод getItem PagerAdapter выглядит следующим образом:
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return mSummaryFragment;
case 1:
return mDetailsFragment;
}
return null;
}
При первом запуске все работает нормально, но когда ориентация меняется, я получаю эту ошибку в logcat независимо от того, как меняется ориентация (книжная -> альбомная или наоборот):
java.lang.IllegalStateException: невозможно изменить идентификатор контейнера фрагмента. SummaryFragment{40dd1800 #1 id=0x7f0b004a android:switcher:2131427400:0}: было 2131427402, теперь 2131427400
Я не совсем уверен, что это лучший способ сделать то, что я хочу, однако сохранение фрагментов в пакет и их извлечение было уловкой, которую я заметил в исходном коде Google IO 2013, поэтому я надеюсь, что это хотя бы частично верно.