Задача — реализовать «бесконечную» прокрутку страниц с использованием ViewPager и PagerAdapter. В качестве элементов выступают View (не Fragment). Все view создаются из единого xml-layout через inflater, отличаются лишь содержанием. Содержание подгружается из API.
В параметрах ViewPager установил ограничение на лимит неактивных страниц слева и справа:
mViewPager.setOffscreenPageLimit(1);
Т.о., одновременно могут храниться 1 активная страница и по 1 слева и справа, в случае если их становится больше, вызывается соотв. метод на удаление в PagerAdapter-e. При запуске имеется 1 id, для которого загружается содержание из Интернета с API (картинка + текст). После загрузки первой страницы апи присылает ответ с id следующей страницы, если таковая имеется. id-шники страниц храню в ArrayList: при создании адаптера инициализирую этот список первым значением (id начальной страницы), при получении следующего id добавляю туда следующее значение. Получается, при запуске у меня имеется адаптер, getCount которого возвращает размер этого массива id (mPagesId), в начале он равен 1. Далее адаптер запрашивает 0-вую позицию для ViewPager-a:
@Override
public Object instantiateItem(ViewGroup collection, int position) {
int pageId = Integer.valueOf(mPagesId.get(position));
View newView = createNewView();
newView.setId(pageId);
((ViewPager) collection).addView(newView);
// start post loading if there is active network connection
if (ConnectionUtils.isOnline(mContext)) {
TaskLoadPost loadPostTask = new TaskLoadPost();
loadPostTask.execute(pageId);
} else {
DialogUtil.showNetworkErrorDialog((Activity) mContext);
}
return newView;
}
В фоне заполняю вьюхи данными из Сети и там же получаю новый id, который добавляю в массив:
mPagesId.add(id);
После чего адаптер вновь вызывает метод instantiateItem(...), далее по позиции берется id из массива и все повторяется далее: добавили новое view, загрузили его, загрузили след. Id, поместили в массив и т.д.
На первых шагах все в порядке (рассматриваю только листание вправо сейчас), разве что по достижению 3 или 4 элемента адаптер перед инициализацией новой страницы вызывает метод удаления destroyItem():
((ViewPager) collection).removeView((View) view);
View page = (View) view;
mPagesId.remove(String.valueOf(page.getId()));
notifyDataSetChanged();
ОК, удалили, все вроде бы в порядке. После этого размер массива становится равным 3м. Тут начинается самое интересное: после удаления 0 элемента мы в методе initiate вызываемся уже не как логично было бы предполагать со 2 элементом — position == 2 (ведь у нас хранится только 3 страницы), а с 3 — мы лезем по этой позиции за Id, но id там не находим, т.к. массив только что был «сжат». Ну да ладно, думаю, как-нибудь можно выкрутиться. Проскочили, листнули, вновь удалили, снова попадаем в в initiate… опять же логично ожидать position == 2, 3 ну или черт с ним, 4… но position приходит равным 1! Что это за единица и откуда и почему она берется — для меня большая загадка. Опять же говнокодом это можно обойти и в случае листания вправо далее вызывается только с позицией = 1 — почему и как мне не ясно.
В общем, суть вопроса: каким образом можно нормально синхронизировать и «подружить» какую-то свою структуру, храняющуюю вспомогательные данные для страниц во ViewPager, с тем поведением, что происходит у ViewPager-a и вызываемыми им методами добавления\удаления с непонятными позициями. Мне действительно нужен дополнительный массив синхронизированный с внутренним хранилищем View во ViewPager, иначе не представляется возможным загружать следующие\предыдущие страницы с API с правильными id-шниками, при этом удаляя ненужные страницы и id. Кто-нибудь сталкивался с чем-то подобным? Может, есть какие-то более элегантные задачи решить мою задачу? Может, я как-то не верно понимаю всю хитрость того, когда и как ViewPager вызывает методы своего адаптера? Для меня эти позиции действительно неясны, а без возможности их предсказания я не могу получать нужные id для загрузки следующих страниц и очистки старых.
Был бы очень благодарен за любой совет, бьюсь над этим уже порядка недели…