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"); } } 
  • Utilizar varios diseños en ViewPageIndicator
  • ViewPager dentro de Fragmento pierde contenido al volver a él
  • Uso de la fuente personalizada en viewpagerindicator
  • Android: ViewPagerIndicator - Creación de diferentes diseños para diferentes páginas
  • Cómo cambiar el estilo de texto TabPageIndicator - Negrita, TextSize en seleccionado?
  • Asistente condicional / inicialización con ViewPager
  • Quitar TabIndicator de PagerTabStrip en un ViewPager
  • Dar texto de la pestaña seleccionada un color diferente utilizando ViewPagerIndicator
  • El ViewPagerIndicator no es fácil con 1000 páginas
  • ViewPagerIndicator - Establece TabPageIndicator en el centro
  • TabPageIndicator no estilo correctamente dentro de Fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.