Предотвратить 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();
    }
}
Другие вопросы по тегам