Предотвратить ViewPager от разрушения за пределами экрана
У меня ViewPager подключен к FragmentPagerAdapter, который отображает три фрагмента. ViewPager, по-видимому, разрушает представление размещенного фрагмента, когда он находится более чем в одном ударе от текущей позиции.
Все эти представления являются простыми списками, и эта оптимизация совершенно не нужна, поэтому я бы хотел ее отключить. Это вызывает некоторые визуальные проблемы, потому что к спискам применены анимации макета, и эти анимации воспроизводятся после того, как они были уничтожены и воссозданы. Он также показывает анимацию введения полосы прокрутки каждый раз (когда полоса прокрутки кратко видна, чтобы указать, что прокрутка возможна), что может отвлекать, и текущая позиция прокрутки пользователя теряется в процессе.
Он также не загружает третий фрагмент до тех пор, пока не произойдет первый удар, что является проблематичным, поскольку каждый фрагмент обрабатывает свои собственные вызовы службы, и я предпочел бы, чтобы все три запускались одновременно, когда загружается действие. Задержка третьего сервисного звонка не идеальна.
Есть ли способ убедить ViewPager прекратить это поведение и просто сохранить все мои фрагменты в памяти?
4 ответа
В 4-й редакции пакета поддержки в ViewPager был добавлен метод, позволяющий указать количество используемых закадровых страниц, а не значение по умолчанию, равное 1.
В вашем случае вы хотите указать 2, чтобы при переходе на третью страницу первая не уничтожалась, и наоборот.
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(2);
По умолчанию ViewPager воссоздает фрагменты при перелистывании страницы. Чтобы предотвратить это, вы можете попробовать одну из двух вещей:
1. В onCreate() ваших фрагментов вызовите setRetainInstance (true).
2. Если количество фрагментов фиксировано и относительно мало, то в onCreate() добавьте следующий код:
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(3);
Если я правильно помню, второй вариант более перспективный. Но я призываю вас попробовать оба и посмотреть, какие из них работают.
"Установите количество страниц, которые должны быть сохранены на любой стороне текущей страницы в иерархии представлений в состоянии ожидания. Страницы, превышающие этот предел, будут воссозданы из адаптера при необходимости".
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
Выбранный ответ хорош, но не очень хорош для меня. Это потому, что у меня было много фрагментов (20-30), поэтому загрузка активности с ViewPager заняла бы много времени, если бы я использовал setOffscreenPageLimit(30). В моем случае мне пришлось реализовать метод destroyItem() (в классе адаптера ViewPager) и удалить вызов суперфункции. Вот псевдокод
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
}
Теперь, если вы хотите больше контекста, вот весь класс ViewPagerAdapter.
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> listFragment =
new ArrayList<>();
public ViewPagerAdapter(@NonNull FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return listFragment.get(position);
}
@Override
public int getCount() {
return listFragment.size();
}
/*This is the method I was taking about*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
}
public void addFragment(Fragment fragment)
{
listFragment.add(fragment);
notifyDataSetChanged();
}
}