2012-10-07 20 views
5

Después de haber buscado con anterioridad sobre este tema, puedo encontrar muchas discusiones sobre cómo agregar y eliminar dinámicamente Fragment s seleccionados de un ViewPager. Lo que realmente me preocupa aquí es cómo puedo eliminar programáticamente ViewPager 'limpiamente' de su ViewGroup, cuando ese ViewPager se ha usado para mostrar Fragment s a través de , y asegurar que los Fragment s que se destruyen correctamente .Eliminación mediante programación de una ViewPager, ¿cuándo (o cómo puedo garantizar) que los fragmentos contenidos se destruyan?

Para ampliar la pregunta un poco más, tengo un diseño de dos paneles de paisaje donde se hace una selección de una lista dentro de un Fragment en el lado izquierdo, y el contenido elegido se coloca a la derecha dentro de a FrameLayout. La clave es que el contenido puede ser paginado o no. Por lo tanto, el contenido debe mostrarse en un formato ViewPager o, si no está paginado, se representará directamente con un solo Fragment.

Para mostrar una única Fragment, que sólo tiene que realizar una FragmentTransaction como lo haría normalmente con el fin de colocar el Fragment en el recipiente FrameLayout. Si, por otro lado, se muestra el contenido paginado, en su lugar creo un ViewPager y lo agrego como hijo del FrameLayout.

Cuando necesito cambiar el contenido, entonces si el contenido anterior era un Fragment independiente, entonces simplemente puedo eliminarlo a través de FragmentTransaction.remove(). Cuando hago esto, el Fragment pasa por el ciclo onPause() ... onDestroy() como se esperaba. Si el contenido anterior era ViewPager, entonces lo elimino del FrameLayout usando .removeAllViews(). Aquí llego al problema: no veo ninguno de los métodos onPause() ... onDestroy() que se llama en ninguno de los Fragment s que se llevaron a cabo dentro de ese ViewPager a través del FragmentPagerAdapter.

Desde el punto de vista del usuario, la aplicación funciona bien. Después de eliminar varias rondas de ViewPager, puedo ver la memoria de recuperación de GC. Sin embargo, no me gusta el hecho de que esos Fragment s 'métodos de fin de vida no se llaman ya que no puedo hacer ninguna limpieza dentro de ellos, y simplemente no parece' correcto '.

¿Hay un método que pueda enganchar en el fin de eliminar la ViewPager 's Fragment s cuando el ViewPager se separa de su padre, tal vez? En otras palabras, cuando sé que el ViewGroup ya no está en uso, realizaría FragmentTransaction en algún lugar (quizás en el FragmentPagerAdapter) para eliminar esos Fragment s.

Como alternativa, me doy cuenta de que podría mantener el ViewPager a la derecha de forma permanente, y cambiar dinámicamente el Fragment s dentro de él. Por supuesto, simplemente no importaría que en ciertos momentos solo tuviera una página. Si esta sería una mejor manera de hacerlo, haré una refactorización de mi código para hacer esto, pero apreciaría las opiniones.

Respuesta

12

Sin embargo, no me gusta el hecho de que los métodos de fin de vida de los Fragments no se llamen ya que no puedo hacer ninguna limpieza dentro de ellos, y simplemente no parece "correcto".

Deben limpiarse cuando se destruya la actividad, si eso no es demasiado tarde para usted (por ejemplo, problemas de pila).

En otras palabras, cuando sé que el ViewGroup ya no se usa, me gustaría realizar FragmentTransactions en alguna parte (tal vez en el FragmentPagerAdapter) para eliminar esos fragmentos es.

No ejecutó las transacciones para poner allí los fragmentos. Por lo tanto, no puede ejecutar fácilmente las transacciones para eliminar los fragmentos. Si cambia al FragmentStatePagerAdapter, y llama al setAdapter(null), debe destruir todos los fragmentos existentes en el buscapersonas, al leer el código fuente. FragmentPagerAdapter nunca utiliza remove(), pero FragmentStatePagerAdapter hace, de su método destroyItem(), y todos los fragmentos existentes son destruidos a través de destroyItem() cuando se suministra un nuevo adaptador (o null) para setAdapter().

+1

Gracias. Una solución que encontré ahora es usar 'FragmentManager' dentro de' destroyItem' para eliminar el 'Fragment'. También devuelvo 'PagerAdapter.POSITION_NONE' de' getItemPosition' y llamo a 'notifyDataSetChanged()'. Al hacer esto antes de eliminar el 'ViewPager', se llama al' Fragment's '' onDestroy' y estoy contento. ¿Ves algún problema con esto? La razón para usar 'FragmentPagerAdapter' es porque quiero que se queden todos los' Fragment's (un número pequeño), porque mi UI requiere que los datos de usuario se conserven de todos los fragmentos en respuesta a una única acción de aceptar el botón. – Trevor

+1

@Trevor: "¿Ves algún problema con esto?" - Eso debería estar bien, pero tenga cuidado al aceptar cualquier actualización del paquete de soporte de Android. Por lo que sabemos, cambiarán el comportamiento de modo que Android también intente destruir los fragmentos, y usted puede terminar con errores y tener que retroceder su propia lógica de destrucción. – CommonsWare

+1

Gracias de nuevo, y entendido. Parece que lo que tengo ahora es lo mejor de ambos mundos: usar 'FragmentPagerAdapter' significa que paginar desde un' Fragment' no lo destruye, pero al extender 'destroyItem' para eliminar el fragmento como lo hace' FragmentStatePagerAdapter', puedo eliminar Fragmentos cuando quiero. (Agradezco que se requiera que todos los fragmentos adjuntos permanezcan para poder solicitarles que persistan los datos de entrada de los usuarios de inmediato podría ser desaprobado, pero de lo contrario tendría que refactorizar para que todos los Fragmentos pasaran estos datos a la Actividad principal, que preferiría evitar.) – Trevor

Cuestiones relacionadas