ViewPager.setCurrentItem работает только с w / smoothScroll, установленным в true

Я создал бесконечное расширение FragmentPagerAdapter (есть примеры того, как добиться этого на этом сайте ). Это позволяет мне перебирать 50 (произвольное число) наборов из 52 фрагментов (один раз в неделю), тем самым давая бесконечное ощущение фрагментов пользователю.

Когда вы прокручиваете / ViewPager.setCurrentItem между фрагментами, вызывая ViewPager.setCurrentItem , есть два сценария, которые я вижу:

  1. Прыгая только один фрагмент в любом случае – все в порядке. Вероятно, это связано с кодом, который специализируется на этом прецеденте в ViewPager.setCurrentItemInternal (ищите комментарий, начинающийся со слов « We are doing a jump by more than one page )
  2. Повторяя более чем один фрагмент, новый фрагмент отображается правильно на экране, только если вызывается setCurrentItem когда smoothScroll установлен в true (т.е. setCurrentItem(i, true) ); В противном случае есть пустой экран

Из того, что я вижу, это, вероятно, потому, что в ViewPager.scrollToItem есть следующий код:

 if (smoothScroll) { smoothScrollTo(destX, 0, velocity); if (dispatchSelected) { dispatchOnPageSelected(item); } } else { if (dispatchSelected) { dispatchOnPageSelected(item); } completeScroll(false); scrollTo(destX, 0); pageScrolled(destX); } 

Это тот момент, когда я вышел из глубины. Почему это, if/else вызывает явления, которые я испытываю?

    Объяснение довольно просто – ViewPager не сохраняет все состояния ваших фрагментов, потому что это будет катастрофой для производительности, если он будет поддерживать все состояния в активном состоянии.

    Для этого случая существует метод setOffscreenPageLimit . Его целью является определение количества состояний фрагментов, которые ViewPager должен сохранять влево и вправо от текущего. Для дополнительной проверки фона официальная документация: https://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)

    Задайте количество страниц, которые должны быть сохранены в обе стороны текущей страницы в иерархии представлений в состоянии ожидания. Страницы, выходящие за этот предел, будут воссозданы с адаптера, если это необходимо.

    Это предлагается как оптимизация. Если вы заранее знаете количество страниц, которые вам понадобятся для поддержки или имеют механизмы ленивой загрузки на ваших страницах, настройка этой настройки может иметь преимущества в воспринимаемой гладкости анимации и взаимодействия пейджинга. Если у вас есть небольшое количество страниц (3-4), которые вы можете сохранить активными одновременно, меньше времени будет потрачено на макет для вновь созданных подтипов просмотра в качестве страниц пользователя взад и вперед.

    Вы должны держать этот предел низким, особенно если ваши страницы имеют сложные макеты. По умолчанию этот параметр равен 1.

    Таким образом, мы можем видеть, что предел по умолчанию равен 1 – это ответ, почему прыжок только одного фрагмента работает отлично. И это также ответ для гладкого случая прокрутки – когда вы хотите установить новый текущий элемент с плавной прокруткой, это означает, что вам нужно прокручивать все фрагменты по одному – и вот в этом случае, когда работает ограничение по умолчанию 1.

    Поэтому в вашем случае вы можете попробовать setOffscreenPageLimit(52) , а затем setCurrentItem(50) должен работать как ожидалось. Это не рекомендуется , просто делайте это, чтобы увидеть поведение. Если у вас есть сложная работа в вашем фрагменте (например, загрузка некоторых данных из сети), это будет большой задержкой при запуске, так как все фрагменты будут загружаться сразу.

    Надеюсь, это поможет!