|
||
|
![]() |
![]() |
Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android |
![]() |
|
Herramientas |
#1
|
||||
|
||||
No perder datos del fragment al girar
Bueno basicamente mi duda es la que esta descripta en el titulo del tema.
Tengo un navigation drawer y al girar la pantalla pierdo los datos del fragment actual.. cual seria la mejor forma de poder guardar esos datos y recuperarlos despues? porque con las activitys estan los metodos onRestore y OnSave.. pero en los fragment estos metodos no estan. Saludos |
|
#2
|
||||
|
||||
Lo que tienes que hacer en la Activity es almacenar el Fragment y luego recuperarlo. El Fragment no se destruye por girar la Activity, sigue estando en el FragmentManager.
|
#3
|
||||
|
||||
Para lo que dice kriogeN, tienes que hacer add o replace poniendo un tag y luego usar fragmentManager.findFragmentByTag(tag) (o algo similar), lo cual te dará el fragment anterior.
Un saludo. |
#4
|
||||
|
||||
Lo que dice Arasthel funciona en la mayoría de los casos, pero si la Activity se ha destruido es probable que cuando vayas a buscar el Fragment no lo encuentres, si cuando se vuelva a crear la Activity quieres estar 100% seguro de que lo vas a encontrar tienes que almacenarlo en el Bundle, igual que cualquier otro objeto de la Activity que quieras almacenar, sólo que se hace de una forma especial, lo que yo hago es lo siguiente:
En el onSaveInstanceState hago esto: @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); getSupportFragmentManager().putFragment(outState, "crearplanfragment", fragment); } Y en el onCreate hago esto: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ................... fragment = new CrearPlanFragment(); if (savedInstanceState==null) fragment = new CrearPlanFragment(); else fragment = (CrearPlanFragment) getSupportFragmentManager().getFragment(savedInsta nceState, "crearplanfragment"); ............. } Por cierto que yo nunca uso el onRestoreInstanceState, prefiero comparar si el savedInstanceState del onCreate es NULL. |
Los siguientes 3 usuarios han agradecido a kriogeN su comentario: | ||
#6
|
||||
|
||||
De nada, yo lo descubrí a base de FCs continuos debido a los Fragment al recuperar una Activity. Desde entonces lo pongo en todas las Activities en las que uso Fragments y sin problemas.
|
#7
|
||||
|
||||
Lo que dice Arasthel funciona en la mayoría de los casos, pero si la Activity se ha destruido es probable que cuando vayas a buscar el Fragment no lo encuentres, si cuando se vuelva a crear la Activity quieres estar 100% seguro de que lo vas a encontrar tienes que almacenarlo en el Bundle, igual que cualquier otro objeto de la Activity que quieras almacenar, sólo que se hace de una forma especial, lo que yo hago es lo siguiente:
En el onSaveInstanceState hago esto: @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); getSupportFragmentManager().putFragment(outState, "crearplanfragment", fragment); } Y en el onCreate hago esto: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ................... fragment = new CrearPlanFragment(); if (savedInstanceState==null) fragment = new CrearPlanFragment(); else fragment = (CrearPlanFragment) getSupportFragmentManager().getFragment(savedInsta nceState, "crearplanfragment"); ............. } Por cierto que yo nunca uso el onRestoreInstanceState, prefiero comparar si el savedInstanceState del onCreate es NULL. ![]() |
#8
|
||||
|
||||
¿Estás usando la clase Fragment del paquete de soporte (android.support.v4.fragment o subclases), o la del API 11 (android.app.Fragment)? Si usas la primera el código te valdrá, si usas la segunda tendrás que usar getFragmentManager en lugar de getSupportFragmentManager. Y si no es eso, te esta fallando por otra cosa, tendrás que tracear el error. |
Gracias de parte de: | ||
#9
|
||||
|
||||
Va dentro de la Activity, que es la que estás recuperando y por tanto la que quieres obtener el Fragment anterior.
¿Estás usando la clase Fragment del paquete de soporte (android.support.v4.fragment o subclases), o la del API 11 (android.app.Fragment)? Si usas la primera el código te valdrá, si usas la segunda tendrás que usar getFragmentManager en lugar de getSupportFragmentManager. Y si no es eso, te esta fallando por otra cosa, tendrás que tracear el error. ![]() Enviado desde mi XT1040 mediante Tapatalk |
#10
|
||||
|
||||
CrearPlanFragment es un ejemplo, así es como se llama el fragment del que he cogido el ejemplo. Tienes que sustituirlo por TU fragment.
|
Gracias de parte de: | ||
#11
|
||||
|
||||
Lo que dice Arasthel funciona en la mayoría de los casos, pero si la Activity se ha destruido es probable que cuando vayas a buscar el Fragment no lo encuentres, si cuando se vuelva a crear la Activity quieres estar 100% seguro de que lo vas a encontrar tienes que almacenarlo en el Bundle, igual que cualquier otro objeto de la Activity que quieras almacenar, sólo que se hace de una forma especial, lo que yo hago es lo siguiente:
En el onSaveInstanceState hago esto: @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); getSupportFragmentManager().putFragment(outState, "crearplanfragment", fragment); } Y en el onCreate hago esto: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ................... fragment = new CrearPlanFragment(); if (savedInstanceState==null) fragment = new CrearPlanFragment(); else fragment = (CrearPlanFragment) getSupportFragmentManager().getFragment(savedInsta nceState, "crearplanfragment"); ............. } Por cierto que yo nunca uso el onRestoreInstanceState, prefiero comparar si el savedInstanceState del onCreate es NULL. ![]() Mi problema es que tengo diferentes fragments que cargo con el drawermenu, pero a la hora de salvarlo como comentas me da force close, ¿solo puedo salvar un fragment? y en ese caso com se que fragment tendría guardado a la hora de recuperarlo para hacer el cast al tipo de mi fragment? Por otro lado, ¿que manera es mejor de manejar los fragment ? Es mejor hacer un new mifragment() cada vez que pulso la opción del menu, o inicializar todos los fragment al empezar la actividad y luego ir reemplazandolos. haciendo un new cada vez que pulso pierdo suavidad en la aplicación cuando pulso de nuevo el mismo menu, y con la segunda opción aveces pierdo datos
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack Última edición por Dild0 Día 02/12/15 a las 10:37:37. |
#12
|
||||
|
||||
Buenas, voy a recuperar este hilo ya que me estoy ayudando de el, y me sucenden cosas estrañas o no se aplicarlo bien.
Mi problema es que tengo diferentes fragments que cargo con el drawermenu, pero a la hora de salvarlo como comentas me da force close, ¿solo puedo salvar un fragment? y en ese caso com se que fragment tendría guardado a la hora de recuperarlo para hacer el cast al tipo de mi fragment? Por otro lado, ¿que manera es mejor de manejar los fragment ? Es mejor hacer un new mifragment() cada vez que pulso la opción del menu, o inicializar todos los fragment al empezar la actividad y luego ir reemplazandolos. haciendo un new cada vez que pulso pierdo suavidad en la aplicación cuando pulso de nuevo el mismo menu, y con la segunda opción aveces pierdo datos ![]() Ahora bien, lo que te ocurre de que algunas veces el Fragment está vacío es porque por falta de memoria se ha destruido su estado y se ha vuelto a crear. Para solucionar este problema debes usar el onSavedInstanceState DEL FRAGMENT!!!, y recuperarlo en el onCreateView, también del Fragment. En un principio el código de la Activity no lo necesitas, salvo que también quieras que los datos prevalezcan si la Activity se destruye, es decir, sales de ella y vuelves al rato. |
#13
|
||||
|
||||
Si quieres recuperar los datos del Fragment la última vez que visitaste el menú, obviamente debes crearlos todos al principio y luego ir reemplazándolos. Si haces new cada vez siempre estarán vacíos y no tendrán savedInstanceState.
Ahora bien, lo que te ocurre de que algunas veces el Fragment está vacío es porque por falta de memoria se ha destruido su estado y se ha vuelto a crear. Para solucionar este problema debes usar el onSavedInstanceState DEL FRAGMENT!!!, y recuperarlo en el onCreateView, también del Fragment. En un principio el código de la Activity no lo necesitas, salvo que también quieras que los datos prevalezcan si la Activity se destruye, es decir, sales de ella y vuelves al rato. ![]() ![]() ![]() ![]() Por cierto estoy pensando, ¿que salvas el fragment entero como en el activity o tengo que salvar dato a dato de mi fragment?
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack Última edición por Dild0 Día 02/12/15 a las 11:43:41. |
#14
|
||||
|
||||
Tienes que salvar dato a dato del fragment, en la Activity sería igual si usases el onSavedInstanceState de la Activity.
|
Gracias de parte de: | ||
#15
|
||||
|
||||
@kriogeN
Ha funcionado muy bien pero tengo otro null pointer, mi fragment tiene un asyntask lo ejecuto bastantes veces y al girar la pantalla y el activity morir como se estaba ejecutando ese hilo al preguntar por getactivity() en el post execute salta el error. Estoy tratando de hacer asyncTask.cancel(true); en el onpause del fragment pero no hace nada o si porque aveces si me cancela(tengo un mensaje) y no rompe Es como si justo muriese el activity mientras se esta ya ejecutando el postexecute ![]() Fragment MyFragmentInfo{a3dc9e} not attached to Activity
at android.support.v4.app.Fragment.getResources(Fragm ent.java:639) at com.r.raul.down.MainDeviceInfo$5.onPostExecute(MyF ragmentInfo.java:442) ![]() EDITO: creo que lo arregle preguntando que solo acceda en el postexecute llamando a: ![]() if (!asyncTask.isCancelled())
![]() saludos
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack Última edición por Dild0 Día 03/12/15 a las 20:30:10. |
#16
|
||||
|
||||
Yo siempre que puede haber un hilo (ya sea un AsyncTask, un Listener o lo que sea) que quiera acceder al getActivity del Fragment consulto si getActivity es != null antes de ejecutarlo.
Hasta ahora ningún problema. Pero si tienes un proceso que ejecuta un hilo en bucle haces bien en cancelarlo y no dejar que sea el sistema el que lo haga por ti. |
Gracias de parte de: | ||
![]() |
![]() |
||||||
|