¿Cuál es la diferencia entre FragmentPagerAdapter
y FragmentStatePagerAdapter
?
Sobre 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 más estáticos para ser buscados, como un conjunto de pestañas. El fragmento de cada página que visita el usuario se mantendrá en la memoria, aunque su jerarquía de visualización puede destruirse cuando no sea visible. Esto puede resultar en el uso de una cantidad significativa de memoria ya que las instancias de fragmentos pueden retener una cantidad arbitraria de estado. Para conjuntos de páginas más grandes, considere
FragmentStatePagerAdapter
.
Y sobre FragmentStatePagerAdapter
:
Esta versión del localizador es más útil cuando hay una gran cantidad de páginas, ya que funciona más como una vista de lista. Cuando las páginas no son visibles para el usuario, su fragmento completo puede destruirse, solo manteniendo el estado guardado de ese fragmento. Esto permite que el localizador conserve mucha menos memoria asociada con cada página visitada en comparación con
FragmentPagerAdapter
el costo de una sobrecarga potencial al cambiar de página.
Entonces 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 Fragment2
, lo cual es simple ListFragment
. Fragment3
también es a ListFragment
.
Entonces mis preguntas son : ¿Qué adaptador debo usar? FragmentPagerAdapter
o FragmentStatePagerAdapter
?
FragmentPagerAdapter
yFragmentStatePagerAdapter
pero lo que esFragmentStateAdapter
?Respuestas:
Como dicen los documentos, piénselo 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. Desea cargar y destruir
Fragments
mientras el usuario lee. En este caso lo usarásFragmentStatePagerAdapter
. Si solo está mostrando 3 "pestañas" que no contienen muchos datos pesados (comoBitmaps
), entoncesFragmentPagerAdapter
podría ser adecuado para usted. Además, tenga en cuenta que,ViewPager
de forma predeterminada, cargará 3 fragmentos en la memoria. Lo primeroAdapter
que menciona puede destruir laView
jerarquía y volver a cargarla cuando sea necesario, la segundaAdapter
solo guarda el estado de laFragment
y la destruye por completo, si el usuario vuelve a esa página, se recupera el estado.fuente
FragmentPagerAdapter
usarlo.FragmentPagerAdapter
es que cambiar entre fragmentos podría ser mucho más rápido, ya que losFragment
objetos reales no necesitan ser reconstruidos cada vez. Por otro lado, esto terminaría usando más memoria que contiene los objetos de fragmento en memoria.viewPager.setOffscreenPageLimit(2)
.FragmentPagerAdapter
almacena todo el fragmento en la memoria y podría aumentar la sobrecarga de la memoria si se usa una gran cantidad de fragmentosViewPager
.Por el contrario, su hermano
FragmentStatePagerAdapter
solo almacena el estado guardado de fragmentos y destruye todos los fragmentos cuando pierden el foco.Por
FragmentStatePagerAdapter
lo tanto, debe usarse cuando tengamos que usar fragmentos dinámicos, como fragmentos con widgets, ya que sus datos podrían almacenarse en elsavedInstanceState
archivo. También no afectará el rendimiento incluso si hay una gran cantidad de fragmentos.Por el contrario, su hermano
FragmentPagerAdapter
debe usarse cuando necesitemos almacenar todo el fragmento en la memoria.Cuando digo que todo el fragmento se guarda en la memoria, significa que sus instancias no se destruirán y crearían una sobrecarga de memoria. Por lo tanto, se recomienda usar
FragmentPagerAdapter
solo cuando haya un número bajo de fragmentosViewPager
.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 más detallados,
FragmentStatePagerAdapter:
con
FragmentStatePagerAdapter
, su fragmento innecesario se destruye. Una transacción se compromete a eliminar completamente el fragmento de su actividadFragmentManager
.El estado
FragmentStatePagerAdapter
viene del hecho de que guardará el fragmentoBundle
desavedInstanceState
cuando se destruye. Cuando el usuario navega hacia atrás, el nuevo fragmento se restaurará utilizando el estado del fragmento.FragmentPagerAdapter:
Por comparación
FragmentPagerAdapter
no se hace nada por el estilo. Cuando el fragmento ya no es necesario.FragmentPagerAdapter
llamadetach(Fragment)
a la transacción en lugar deremove(Fragment)
.Esto destruye la vista del fragmento pero deja viva la instancia del fragmento en el
FragmentManager
.so los fragmentos creados en elFragmentPagerAdapter
nunca se destruyen.fuente
Aquí hay un ciclo de vida de registro de cada fragmento en el
ViewPager
que hay 4 fragmentos yoffscreenPageLimit = 1 (default value)
FragmentStatePagerAdapter
Ir al Fragmento1 (actividad de lanzamiento)
Ir al fragmento 2
Ir al fragmento 3
Ir al fragmento 4
FragmentPagerAdapter
Ir al Fragmento1 (actividad de lanzamiento)
Ir al fragmento 2
Ir al fragmento 3
Ir al fragmento 4
Conclusión :
FragmentStatePagerAdapter
llameonDestroy
cuando se supere el FragmentooffscreenPageLimit
mientrasFragmentPagerAdapter
no.Nota : Creo que deberíamos usar
FragmentStatePagerAdapter
unaViewPager
que tenga mucha página porque será buena para el rendimiento.Ejemplo de
offscreenPageLimit
:Si vamos a Fragment3, que se Detroy Fragment1 (o si tenga Fragment5) debido
offscreenPageLimit = 1
. Si establecemosoffscreenPageLimit > 1
que no va a destruir.Si en este ejemplo, establecemos
offscreenPageLimit=4
, no hay diferencia entre usarFragmentStatePagerAdapter
oFragmentPagerAdapter
porque Fragment nunca llamaonDestroyView
yonDestroy
cuando cambiamos la pestañaDemostración de Github aquí
fuente
Algo que no se dice explícitamente en la documentación o en las respuestas en esta página (aunque implícito por @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, si vuelve a ejecutar la consulta para actualizar listView en el Fragmento), debe usar FragmentStatePagerAdapter.
Mi punto principal aquí es que la cantidad de Fragmentos y si son similares o no no siempre es el aspecto clave a considerar. Si sus fragmentos son dinámicos o no también es clave.
fuente
FragmentPagerAdapter
en mi actividad que usa un ViewPager para mostrar dos fragmentos, donde cada fragmento contiene una lista. Mi primera lista se llama "Todos los informes" y la segunda lista es "Informes favoritos". En la primera lista, si toco el icono de estrella para un informe, actualiza la base de datos para alternar el estado favorito de ese informe. Luego deslizo y veo con éxito este informe en la interfaz de usuario de la segunda lista. Así que tal vez los casos se mantienen en la memoria, pero en algunos casos (por ejemplo, la mía) el contenido en realidad se actualizará bien para FragmentPagerAdapterFragmentPagerAdapter
almacena los datos anteriores que se obtienen del adaptador mientrasFragmentStatePagerAdapter
toma el nuevo valor del adaptador cada vez que se ejecuta.fuente
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 estadoInstanceState del fragmento para su uso posterior. De esta forma, se utiliza una pequeña cantidad de memoria y se entrega un mejor rendimiento en caso de fragmentos dinámicos.
fuente
FragmentPagerAdapter : el fragmento de cada página que visita el usuario se almacenará en la memoria, aunque se destruirá la vista. Por lo tanto, cuando la página vuelva a estar visible, la vista se volverá a crear pero la instancia del fragmento no se volverá a crear. Esto puede ocasionar que se use una cantidad significativa de memoria. FragmentPagerAdapter debe usarse cuando necesitamos almacenar todo el fragmento en la memoria. FragmentPagerAdapter llama a detach (Fragment) en la transacción en lugar de eliminar (Fragment).
FragmentStatePagerAdapter : la instancia del fragmento se destruye cuando no es visible para el usuario, excepto el estado guardado del fragmento. Esto resulta en el uso de solo una pequeña cantidad de memoria y puede ser útil para manejar conjuntos de datos más grandes. Debería usarse cuando tengamos que usar fragmentos dinámicos, como fragmentos con widgets, ya que sus datos podrían almacenarse en el estado guardado de la entrada. Tampoco afectará el rendimiento incluso si hay una gran cantidad de fragmentos.
fuente