Diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter


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

Acerca de FragmentPagerAdapter La guía de Google dice:

Esta versión del buscapersonas es la mejor para usar cuando hay un puñado de típicamente más fragmentos estáticos para ser paginados a través, como un conjunto de pestañas. El fragmento de cada página que visita el usuario se mantendrá en memoria, aunque su jerarquía de vista puede ser destruida cuando no es visible. Esto puede resultar en el uso de una cantidad significativa de memoria desde el fragmento las instancias pueden contener a una cantidad arbitraria de estado. Para juegos más grandes de páginas, considere FragmentStatePagerAdapter.

Y alrededor de FragmentStatePagerAdapter:

Esta versión del buscapersonas es más útil cuando hay un gran número de páginas, trabajando más como una vista de lista. Cuando las páginas no son visibles para el usuario, su fragmento entero puede ser destruido, sólo manteniendo el estado guardado de ese fragmento. Esto permite que el buscapersonas se aferre a mucho menos memoria asociada con cada página visitada como en comparación con FragmentPagerAdapter a costa de potencialmente más gastos generales cuando cambiar de página.

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

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

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

6 answers

Como dicen los documentos, piénsalo de esta manera. Si tuvieras que hacer una aplicación como un lector de libros, no querrás cargar todos los fragmentos en la memoria a la vez. Le gustaría cargar y destruir Fragments mientras el usuario lee. En este caso se utilizará FragmentStatePagerAdapter. Si solo está mostrando 3 "pestañas" que no contienen muchos datos pesados (como Bitmaps), entonces FragmentPagerAdapter podría adaptarse bien. Además, tenga en cuenta que ViewPager por defecto cargará 3 fragmentos en la memoria. La primera Adapter que mencionas podría destruye la jerarquía View y vuelve a cargarla 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.

 241
Author: Emmanuel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-05 15:37:40
  • 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.

  • Por el contrario, su hermano, FragmentStatePagerAdapter solo almacena el savedInstanceState de fragmentos, y destruye todos los fragmentos cuando pierden la concentración.

  • Por lo tanto FragmentStatePagerAdapter debe utilizarse cuando tenemos que utilizar fragmentos dinámicos, como fragmentos con widgets, como sus datos se puede almacenar en el savedInstanceState.También no afectará a la rendimiento incluso si hay un gran número de fragmento.

  • Por el contrario, su hermano FragmentPagerAdapter debe ser utilizado cuando tenemos que almacenar todo el fragmento en la memoria.

  • Cuando digo que todo el fragmento se guarda en la memoria significa, su las instancias no se destruirán y crearán una sobrecarga de memoria. Por lo tanto, se recomienda usar FragmentPagerAdapter solo cuando haya son bajo número de fragmentos para ViewPager.

  • Sería incluso mejor si los fragmentos son estática, ya que lo harían no tener gran cantidad de objetos cuyas instancias serían almacenados.

Para ser más detallado,

FragmentStatePagerAdapter:

  • Con FragmentStatePagerAdapter, su fragmento innecesario es destruir.Una transacción se compromete a eliminar por completo el fragmento de la FragmentManager de tu actividad.

  • El estado en FragmentStatePagerAdapter viene del hecho de que guardará tu fragmento Bundle de savedInstanceState cuando está destruido.Cuando el usuario navega hacia atrás, el nuevo fragmento será restaurado usando el estado del fragmento.

FragmentPagerAdapter:

  • Por comparación FragmentPagerAdapter no hace nada de eso.Cuando el fragmento ya no es necesario.FragmentPagerAdapter llamadas 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 vivo en el FragmentManager. así que los fragmentos creados en el FragmentPagerAdapter nunca son destruir.

 104
Author: Luffy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-11 13:58:21

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

Así que 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 la vista de lista en el Fragmento), debe 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. También es clave que tus fragmentos sean dinámicos o no.

 30
Author: JDenais,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-20 04:43:47

Aquí hay un ciclo de vida de registro de cada fragmento en ViewPager que tienen 4 fragmento 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 Fragmente4

Fragment2: onStop
Fragment2: onDestroyView

Conclusión: FragmentStatePagerAdapter llama onDestroy cuando el Fragmento se supera offscreenPageLimit 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, detroy Fragment1 (o Fragment5 si tiene) porque offscreenPageLimit = 1. Si ponemos offscreenPageLimit > 1, no destruirá.
Si en este ejemplo, establecemos offscreenPageLimit=4, no hay diferencia entre usar FragmentStatePagerAdapter o FragmentPagerAdapter porque Fragment nunca llama onDestroyView y onDestroy cuando cambiamos tab

Github demo aquí

 13
Author: Phan Van Linh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-21 10:31:02

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

 12
Author: vinay kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-14 18:07:47

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

 2
Author: Dwivedi Ji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-05 03:46:35