У меня такое же недопонимание, как работает этот адаптер, и я провел некоторое исследование.
Ключевая особенность заключается в том, что ваши представления хранятся в двух местах:
1 в ViewPager вы добавляете их, вызывая ((ViewPager) container).addView(view);
(здесь вам нужно хранить только три вида, то, что вы видите, и левую и правую окрестности)
2 в private final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();
это член ViewPager, есть сохраненные представления с информацией о их возможностях (они добавляются здесь путем вызова метода адаптера mAdapter.instantiateItem(this, position);
)
static class ItemInfo {
Object object;
int position;
boolean scrolling;
float widthFactor;
float offset;
}
Когда вы скользите, ViewPager
получает позицию вида из массива mItems
или создает его и сравнивает это представление с потомками ViewPager
с помощью метода адаптеров public boolean isViewFromObject(View view, Object object)
.Вид, равный object
, отображается для пользователя на ViewPager
.Если вид отсутствует, то отображается пустой экран.
Вот метод ViewPager
, в котором вид сравнивается с объектом:
ItemInfo infoForChild(View child) {
for (int i=0; i<mItems.size(); i++) {
ItemInfo ii = mItems.get(i);
if (mAdapter.isViewFromObject(child, ii.object)) {
return ii;
}
}
return null;
}
Если позиция представлений из mItems не находится в диапазоне {currentposition -1, текущее положение +1}, тогда оно будет уничтожено:
mItems.remove(itemIndex);
mAdapter.destroyItem(this, pos, ii.object);
представление памяти ViewPager 1
Это одна ловушка с destroyItem
при перемещении впередЕлка называется destroyItem
и затем добавляется новый элемент, но когда вы двигаетесь назад, сначала добавляется новый элемент, а затем старый уничтожается.Если вы попытаетесь использовать только три кэшированных представления, вы можете получить IllegalStateException: The specified child already has a parent.
, скользя назад.
