Вставить страницы в середине FragmentPageAdapter
Я использую ViewPager из ViewPageIndicator, и мне нужно иметь возможность динамически вставлять один фрагмент в средний других.
Я попытался управлять моделью с помощью FragmentPagerAdapter и FragmentStatePagerAdapter (как из кода поддержки v4), так и, похоже, никоим образом не удается вставить страницы посередине.
И второй работает только в том случае, если я наивно выполняю getItemPosition, всегда возвращая POSITION_NONE, но это вызывает полное восстановление страниц каждый раз, когда я сажусь.
Проблема, которую я наблюдал с FragmentStatePagerAdapter (FSP), такова:
- Я начинаю с двух страниц [A] [B]
- Затем я вставляю [C] в середину [A] [C] [B]. После вставки я вызываю notifyDataSetchange()
- Затем FSP вызывает getItemPosition для [A] и получает 0
- Затем FSP вызывает geTItemPosition для [B] и получает 2. И он говорит... Ohhh Я должен уничтожить [B] и сделать mFragments.set(2, null), а затем, поскольку он имеет только два элемента в mFragments array он генерирует исключение IndexOutOfBoundsException
Если немного взглянуть на код, кажется, что если фрагментStatePagerAdapter не поддерживает вставку в середине. Это правильно или я чего-то не хватает?
Update:
Вставка в адаптере выполнена логически, когда верно определенное кодирование, страницы увеличиваются на единицу. Создание фрагмента выполняется с помощью конструктора в getItem() следующим образом:
void setCondition(boolean condition) {
this.condition=condition;
notifyDataSetChanged();
}
public int getCount(){
return condition?3:2;
}
public Fragment getItem(int position) {
if(position==0)
return new A();
else if(position==1)
return condition?new C():new B();
else if(position==2 && condition)
return new B();
else throw new RuntimeException("Not expected");
}
public int getItemPosition(Object object) {
if(object instanceof A) return 0;
else if(object instanceof B) return condition?2:1;
else if(object instanceof C) return 1;
}
Решение:
Как сказано в принятом ответе, ключ состоит в реализации getItemId()
.
Убедитесь, что вы используете хотя бы R9 (июнь 2012 г.) версию библиотеки поддержки Android. Потому что этот метод был добавлен в него. До этой версии этот метод не существует, и адаптер неправильно управляет вставками.
Также убедитесь, что вы используете FragmentPageAdapter, потому что FragmentStatePagerAdapter все еще не работает, потому что он не использует идентификаторы.
Ответы
Ответ 1
Ты забыл об одном методе.
Переопределите getItemId (int position) из FragmentPagerAdapter
, который просто возвращает позицию, чтобы вернуть что-то, что будет идентифицировать экземпляр фрагмента.
public long getItemId(int position) {
switch (position) {
case 0:
return 0xA;
case 1:
return condition ? 0xC : 0xB;
case 2:
if (condition) {
return 0xB;
}
default:
throw new IllegalStateException("Position out of bounds");
}
}