ViewPager + FragmentStatePagerAdapter + изменение ориентации
у меня небольшая проблема: у меня есть ViewPager с некоторыми страницами, и я использую FragmentStatePagerAdapter для обработки данных. В портрете у меня к примеру 20 страниц для ViewPager и в пейзаж я только 10 страниц для ViewPager. Поэтому при изменении ориентации я создаю новый адаптер с другими данными.
вот небольшое объяснение, почему: я показываю одно изображение в портрете и два в пейзаже, но всегда все в счет. Если у меня есть 10 фотографий, чтобы показать, у меня есть 10 в портрете и 5 в пейзаже (всегда два).
но теперь у меня есть странная ошибка: Когда я нахожусь в ландшафте на индексе 5 и поворачиваю устройство, текущая страница ViewPager установлена на 10. Если я поверну его обратно, то окажусь на странице 5. Если я провожу ViewPage сейчас на страницу 10, Methode getItem адаптера никогда не вызывается, и ViewPage показывает мне одно портретное изображение, а не два для ландшафта. Как такое могло случиться? Есть ли кэш в adapter или ViewPager? В onCreate деятельности все создан новый, адаптер, а также данные (только строки с путем) для ViewPager. Итак, есть идеи, как исправить эту действительно страшную "функцию"?
вот код:
onCreate:
mViewPagerAdapter = new ReaderPageViewAdapter(getSupportFragmentManager(), getBaseContext(), mCurrentDocument.mPages, getResources()
.getConfiguration().orientation);
mPageReader = (ReaderViewPager) findViewById(R.id.pager);
mPageReader.setAdapter(mViewPagerAdapter);
адаптер getItem:
public Fragment getItem(final int index) {
final PageInfo pageInfo = mPages.get(index);
final PageFragment pageFragment = (PageFragment) PageFragment
.instantiate(mContext, pageInfo.mClss.getName(), pageInfo.mArgs);
return pageFragment;
}
Если вам нужно что-то еще, просто скажи мне. Спасибо
3 ответов
можно переопределить данные метода onsaveinstance FragmentActivity() и не вызывать супер.данные метода onsaveinstance() в методе.
@Override
protected void onSaveInstanceState(final Bundle outState) {
// super.onSaveInstanceState(outState);
}
не используйте mViewPager.setSaveEnabled(false);
это закончилось большим memoryLeak. После каждого изменения ориентации он помещает фрагменты в массив FragmentManager и никогда не очищает его. Так оно идет до над использования памяти 100mb после изменения ориентации много времен. Методом данные метода onsaveinstance лучше я думать.
у меня тоже возникла эта проблема и я нашел причину.
когда экран вращается,FragmentManager
сохранит все ваши размещенные фрагменты активности, он не будет удалять фрагменты при использовании FragmentStatePagerAdapter
, Вы можете использовать FragmentManager.getFragments()
чтобы проверить количество фрагментов.
пример: активность имеет 4 фрагмента, после 4-кратного изменения ориентации, список FragmentManager.getFragments()
размер будет 20!
я нашел несколько решений:
не вызовите
super.onSaveInstanceState()
из Вас активность, но это кажется не хорошим решением, фрагменты не могут сохранить состояние и восстановить.-
использовать
FragmentPagerAdapter
вместоFragmentStatePagerAdapter
. Но после ориентации изменились, фрагменты которыхViewPager
hosted был отключен(у кого-нибудь еще есть такая же проблема?). Но я могу удалить все фрагменты вActivity.onCreate
исправить. вот так:public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); List<Fragment> fragments = fm.getFragments(); if (fragments != null) { FragmentTransaction transaction = fm.beginTransaction(); for (Fragment fragment : fragments) { transaction.detach(fragment).remove(fragment); } transaction.commitNowAllowingStateLoss(); } ...
но
Fragment.onCreateView()
вызывается дважды.
я все еще ищу идеальный решение :D
Edit:
Я, наконец, решил проблему, это причина моего ViewPager добавить после onStart. При запуске в onStart,FragmentManager
попытается восстановить состояние фрагментов. Я проследил в FragmentManager
, эти код:
Проверьте строку выделения,f.mContainerId
на самом деле это мой идентификатор ViewPager. Тогда это попытаюсь добавить фрагменты представления в ViewPager, в моем случае ViewPager еще не добавлен, поэтому он будет заглушен, но состояние фрагментов ATTACHED
. И в FragmentPagerAdapter.instantiateItem()
, если фрагмент был добавлен, он просто делает attach
фрагмент, Но фрагмент уже прикреплен, поэтому его ничего не делают: (
я добавляю ViewPager в XML-макет активности, его фиксированный.
счастливое кодирование: D
просто вы используете в viewPager.setonpagechangelistener и реализация для кода require примените свое приложение,
http://developer.android.com/reference/android/support/v4/view/ViewPager.html