4

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

При прокрутке/прыжки между фрагментами по телефону 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 вызывает явления, которые я испытываю?

+0

Первое, что я бы посмотрел, это если ваш 'FragmentPagerAdapter # getItem()' правильно вызывается с соответствующими позициями. Похоже, что по какой-то причине они не загружают фрагменты. Вы должны увидеть, что он называется два, может быть, три раза. Один раз в выбранной позиции, один до и один после. – DeeV

+0

@Deev, я добавил записи в logcat, чтобы проверить эту идею. Результат можно найти на странице pastie.org/private/ybvvn5rwl1465haic6fvq. 'getItem' вызывается 3 раза, когда запускается' setCurrentItem (i, false) '(т. е. необъяснимая ситуация). Обратите внимание, что журнал имеет 'getItem (1327)' еще 'newInstance (27)'. Это из-за «бесконечного» зрителя - 1327% 52 = 27 – levengli

+0

@levengi Я не уверен, в чем проблема. Кажется, что пример мог быть с предположением, что плавная прокрутка включена. – DeeV

ответ

2

Объяснение довольно просто - 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) должен работать должным образом. Не рекомендуется, просто сделайте это, чтобы увидеть поведение.Если у вас есть сложная работа в вашем фрагменте (например, загрузка некоторых данных из сети), это приведет к большой задержке при запуске, так как все фрагменты будут загружаться сразу.

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

+0

работал как шарм. спасибо – levengli

+0

Добро пожаловать! – rom4ek