Вставить страницы в середине 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, он бросает Исключение IndexOutOfBoundsException

Немного посмотрев код, кажется, что при условии, что fragStatePagerAdapter не поддерживает вставку посередине. Это правильно или я чего-то не хватает?

Обновление: вставка в адаптере выполнена логически, когда истинное значение кода верно, страницы увеличиваются на единицу. Создание фрагмента выполняется с помощью конструктора в 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() .

Убедитесь, что вы используете, по крайней мере, версию библиотеки поддержки android-поддержки R9 (июнь 2012 г.) . Потому что этот метод был добавлен в него. До этой версии этот метод не существует, и адаптер неправильно управляет вставками. Также убедитесь, что вы используете FragmentPageAdapter, потому что FragmentStatePagerAdapter все еще не работает, потому что он не использует идентификаторы.

Вы забыли об одном методе.
Переопределите 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"); } }