Insertar páginas en el medio de un FragmentPageAdapter

Estoy usando un ViewPager de ViewPageIndicator y necesito poder insertar dinámicamente un fragmento en el medio de otros.

He intentado manejar el modelo con FragmentPagerAdapter y FragmentStatePagerAdapter (ambos del código de soporte v4) y el primero parece no gestionar en modo alguno la inserción de páginas en el medio. Y el segundo sólo funciona si hago una implementación ingenua de getItemPosition volviendo siempre POSITION_NONE pero esto causa la recreación completa de páginas cada vez que golpeo.

El problema que he observado con FragmentStatePagerAdapter (FSP) es el siguiente:

  • Comienzo con dos páginas [A] [B]
  • Entonces inserto [C] en el medio [A] [C] [B]. Después del inserto llamo notifyDataSetchange ()
  • Entonces FSP llama a getItemPosition para [A] y obtiene 0
  • Entonces FSP llama a geTItemPosition para [B] y obtiene 2. Y dice … Ohhh tengo que destruir [B] y hace mFragments.set (2, null) y luego como solo tiene dos elementos en mFragments array que lanza Una excepción IndexOutOfBoundsException

Después de buscar un poco en el código parece que siempre fragmentStatePagerAdapter no admite la inserción en el medio. ¿Es correcto o me falta algo?

Actualización: El inserto en el adaptador se hace de una manera lógica, cuando una cierta codificación es verdadera las páginas se incrementan en uno. La creación del fragmento se hace usando el constructor en getItem () de esa manera:

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; } 

Solución:

Como se dijo en la respuesta aceptada la clave es implementar getItemId() .

Asegúrese de utilizar al menos la versión R9 (junio de 2012) de la biblioteca de soporte de android . Porque este método fue agregado en él. Anterior a esta versión, ese método no existe y el adaptador no gestiona correctamente las inserciones. También asegúrese de utilizar FragmentPageAdapter porque FragmentStatePagerAdapter todavía no funciona porque no utiliza ids.

Te olvidaste de un método.
Anula getItemId (int position) de FragmentPagerAdapter que simplemente devuelve la posición para devolver algo que identificará la instancia del fragmento.

 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"); } } 
  • Accidente después de agregar el elemento al menú de opciones de la barra de acción de Fragmento seguido de cambio de orientación
  • Quitar TabIndicator de PagerTabStrip en un ViewPager
  • ViewPager dentro de Fragmento pierde contenido al volver a él
  • ViewPager con indicador sin la biblioteca de soporte de Android
  • Android ViewPager con puntos inferiores
  • Utilizar varios diseños en ViewPageIndicator
  • Android ViewPager guardar página anterior en onPageSelected
  • ¿Cómo hacer actualizaciones de ViewPager con frecuencia?
  • No se puede agregar ViewPagerIndicator a la aplicación con Gradle
  • Uso de la fuente personalizada en viewpagerindicator
  • ViewPagerIndicator no muestra el texto del título
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.