viewpager ondestroyview example android android-fragments android-viewpager fragmentpageradapter fragmentstatepageradapter

android - ondestroyview - Diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter



fragmentstatepageradapter vs fragmentpageradapter (6)

¿Cuál es la diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter ?

Acerca de FragmentPagerAdapter La guía de Google dice:

Esta versión del buscapersonas es mejor para usar cuando hay un puñado de fragmentos típicamente estáticos, como un conjunto de pestañas. El fragmento de cada página que visiten los usuarios se guardará en la memoria, aunque su jerarquía de vistas puede destruirse cuando no esté visible. Esto puede resultar en el uso de una cantidad significativa de memoria, ya que las instancias de fragmentos pueden conservar una cantidad arbitraria de estado. Para conjuntos de páginas más grandes, considere FragmentStatePagerAdapter.

Y sobre FragmentStatePagerAdapter :

Esta versión del buscapersonas es más útil cuando hay una gran cantidad de páginas, que funcionan más como una vista de lista. Cuando las páginas no son visibles para el usuario, su fragmento completo puede ser destruido, solo manteniendo el estado guardado de ese fragmento. Esto permite que el buscapersonas retenga mucha menos memoria asociada con cada página visitada en comparación con FragmentPagerAdapter, lo que podría generar una sobrecarga mayor al cambiar de página.

Así que solo tengo 3 fragmentos. Pero todos ellos son módulos separados con una gran cantidad de datos.

Fragment1 maneja algunos datos (que ingresan los usuarios) y los pasa a través de la actividad a Fragment2 , que es solo un simple ListFragment . Fragment3 también es un ListFragment .

Así que mis preguntas son : ¿Qué adaptador debo usar? FragmentPagerAdapter o FragmentStatePagerAdapter ?


Algo que no se dice explícitamente en la documentación o en las respuestas en esta página (aunque implícito en @Naruto), es que FragmentPagerAdapter no actualizará los Fragmentos si los datos en el Fragmento cambian porque mantiene el Fragmento en la memoria.

Entonces, incluso si tiene un número limitado de Fragmentos para mostrar, si desea poder actualizar sus fragmentos (por ejemplo, vuelva a ejecutar la consulta para actualizar el listView en el Fragmento), necesita usar FragmentStatePagerAdapter.

Mi punto aquí es que el número de Fragmentos y si son o no similares no siempre es el aspecto clave a considerar. Si tus fragmentos son dinámicos también es clave.


Aquí hay un ciclo de vida de registro de cada fragmento en ViewPager que tiene 4 fragmentos y offscreenPageLimit = 1 (default value)

FragmentStatePagerAdapter

Ir a Fragment1 (actividad de lanzamiento)

Fragment1: onCreateView Fragment1: onStart Fragment2: onCreateView Fragment2: onStart

Ir a Fragment2

Fragment3: onCreateView Fragment3: onStart

Ir a Fragment3

Fragment1: onStop Fragment1: onDestroyView Fragment1: onDestroy Fragment1: onDetach Fragment4: onCreateView Fragment4: onStart

Ir a Fragment4

Fragment2: onStop Fragment2: onDestroyView Fragment2: onDestroy

FragmentPagerAdapter

Ir a Fragment1 (actividad de lanzamiento)

Fragment1: onCreateView Fragment1: onStart Fragment2: onCreateView Fragment2: onStart

Ir a Fragment2

Fragment3: onCreateView Fragment3: onStart

Ir a Fragment3

Fragment1: onStop Fragment1: onDestroyView Fragment4: onCreateView Fragment4: onStart

Ir a Fragment4

Fragment2: onStop Fragment2: onDestroyView

Conclusión : FragmentStatePagerAdapter llama onDestroy cuando se supera el Fragmento offscreenPageLimit onDestroy mientras que FragmentPagerAdapter no.

Nota : creo que deberíamos usar FragmentStatePagerAdapter para un ViewPager que tiene mucha página porque será bueno para el rendimiento.

Ejemplo de offscreenPageLimit :

Si vamos a Fragment3, destruirá Fragmento 1 (o Fragmento 5 si tiene) porque offscreenPageLimit = 1 . Si configuramos offscreenPageLimit > 1 no se destruirá.
Si en este ejemplo, configuramos offscreenPageLimit=4 , no hay ninguna diferencia entre usar FragmentStatePagerAdapter o FragmentPagerAdapter porque Fragment nunca llama onDestroyView y onDestroy cuando cambiamos la pestaña

Demo de Github aquí


Como dicen los doctores, piénsalo de esta manera. Si tuviera que hacer una aplicación como un lector de libros, no querrá cargar todos los fragmentos en la memoria a la vez. Le gustaría cargar y destruir Fragments medida que el usuario lee. En este caso utilizará FragmentStatePagerAdapter . Si solo está mostrando 3 "pestañas" que no contienen una gran cantidad de datos pesados ​​(como Bitmaps ), FragmentPagerAdapter podría serle de utilidad. Además, tenga en cuenta que ViewPager por defecto cargará 3 fragmentos en la memoria. El primer Adapter que mencione podría destruir la jerarquía de View y volver a cargarlo cuando sea necesario, el segundo Adapter solo guarda el estado del Fragment y lo destruye completamente, si el usuario vuelve a esa página, se recupera el estado.


FragmentStatePagerAdapter = Para acomodar una gran cantidad de fragmentos en ViewPager. Como este adaptador destruye el fragmento cuando no es visible para el usuario y solo se guarda el estado de fragmento guardado del fragmento para su uso posterior. De esta manera, se utiliza una cantidad baja de memoria y se entrega un mejor rendimiento en caso de fragmentos dinámicos.


FragmentPagerAdapter almacena los datos anteriores que se obtienen del adaptador, mientras que FragmentStatePagerAdapter toma el nuevo valor del adaptador cada vez que se ejecuta.


  • FragmentPagerAdapter almacena todo el fragmento en la memoria, y podría aumentar la sobrecarga de memoria si se utiliza una gran cantidad de fragmentos en ViewPager .

  • Al contrario que su hermano, FragmentStatePagerAdapter solo almacena el estado de la instancia guardada de los fragmentos, y destruye todos los fragmentos cuando pierden el enfoque.

  • Por lo tanto, FragmentStatePagerAdapter debe usarse cuando tenemos que usar fragmentos dinámicos, como fragmentos con widgets, ya que sus datos podrían almacenarse en el estado de savedInstanceState guardado. savedInstanceState afectará el rendimiento incluso si hay una gran cantidad de fragmentos.

  • Por el contrario, su hermano FragmentPagerAdapter debe usarse cuando necesitamos almacenar todo el fragmento en la memoria.

  • Cuando digo que todo el fragmento se guarda en la memoria, significa que sus instancias no serán destruidas y crearían una sobrecarga de memoria. Por lo tanto, se recomienda usar FragmentPagerAdapter solo cuando hay un número bajo de fragmentos para ViewPager .

  • Sería aún mejor si los fragmentos son estáticos, ya que no tendrían una gran cantidad de objetos cuyas instancias se almacenarían.

Para ser mas detallista,

FragmentStatePagerAdapter:

  • con FragmentStatePagerAdapter , su fragmento innecesario se destruye. Se compromete una transacción para eliminar completamente el fragmento del FragmentManager de su actividad.

  • El estado en FragmentStatePagerAdapter proviene del hecho de que guardará el Bundle de su fragmento de savedInstanceState cuando se savedInstanceState Cuando el usuario navega hacia atrás, el nuevo fragmento se restaurará usando el estado del fragmento.

FragmentPagerAdapter:

  • Por comparación, FragmentPagerAdapter no hace nada de ese tipo. Cuando el fragmento ya no es necesario. FragmentPagerAdapter llama a detach(Fragment) en la transacción en lugar de remove(Fragment) .

  • Esta destrucción es la vista del fragmento, pero deja la instancia del fragmento viva en el FragmentManager los fragmentos creados en el FragmentPagerAdapter nunca se destruyen.