En Android, un fragmento (por ejemplo FragA
) se agrega a la pila y otro fragmento (por ejemplo FragB
) llega a la parte superior. Ahora al devolver el golpe FragA
llega a la cima y onCreateView()
se llama. Ahora me encontraba FragA
en un estado particular antes de que FragB
me pusieran encima.
Mi pregunta es ¿cómo puedo restaurar FragA
a su estado anterior? ¿Hay alguna manera de guardar el estado (como decir en un paquete) y, de ser así, ¿qué método debo anular?
android
android-fragments
pankajagarwal
fuente
fuente
onSaveInstanceState
solo se llama cuando su actividad correspondiente también se está cerrando.Los fragmentos
onSaveInstanceState(Bundle outState)
nunca se llamarán a menos que la actividad del fragmento lo llame a sí mismo y a los fragmentos adjuntos. Por lo tanto, este método no se llamará hasta que algo (generalmente rotación) fuerce la actividadSaveInstanceState
y la restaure más tarde. Pero si solo tiene una actividad y un gran conjunto de fragmentos dentro de ella (con un uso intensivo dereplace
) y la aplicación se ejecuta solo en una orientación, esonSaveInstanceState(Bundle outState)
posible que no se llame durante mucho tiempo.Sé tres posibles soluciones alternativas.
El primero:
use argumentos de fragmentos para contener datos importantes:
La segunda pero menos pedante forma: mantenga las variables en singletons
El tercero: no
replace()
fragmentes sinoadd()
/show()
/hide()
ellos en su lugar.fuente
Fragment.onSaveInstanceState()
nunca fue llamado. Simplemente guarde sus propios datos en el argumento, incluidos los elementos en la vista de lista o solo sus ID (si tiene otro administrador de datos centralizado). No es necesario guardar la posición de la vista de lista, que se guardó y restauró automáticamente.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
siempre es asínull
. ¿Cuál es el problema?getArguments()
es DEFINITIVAMENTE el camino a seguir, incluidos los fragmentos anidados en un ViewPager. Uso 1 actividad e intercambio muchos fragmentos de entrada / salida, y esto funciona perfectamente. Aquí hay una prueba simple para que usted examine cualquier solución propuesta: 1) vaya del Fragmento A al Fragmento B; 2) cambiar la orientación del dispositivo dos veces; 3) presione el botón Atrás en el dispositivo.setArguments(new Bundle());
sobrescribe el antiguo paquete. Así que asegúrese de crear un fragmento solo una vez, y luego use esta instancia en lugar de crear uno nuevo cada vez.Solo tenga en cuenta que si trabaja con Fragments usando ViewPager, es bastante fácil. Sólo tiene que llamar a este método:
setOffscreenPageLimit()
.Acordar a los documentos:
Problema similar aquí
fuente
Simplemente infle su Vista por una vez.
Ejemplo sigue:
}
fuente
Fragment
refiere a que su vista raíz no hará eso. Si bien la referencia por parte de algunos elementos raíz del GC , como la propiedad estática global, la variable de subproceso no ui. UnaFragment
instancia no es raíz de GC, por lo que se puede recolectar basura. También lo hará su vista raíz.Trabajé con un problema muy similar a este. Como sabía que volvería con frecuencia a un fragmento anterior, verifiqué si el fragmento
.isAdded()
era verdadero, y si es así, en lugar de hacer untransaction.replace()
solo hago untransaction.show()
. Esto evita que el fragmento se vuelva a crear si ya está en la pila, sin necesidad de guardar el estado.Otra cosa a tener en cuenta es que, si bien esto preserva el orden natural de los fragmentos, es posible que aún necesite manejar la actividad en sí misma que se destruye y recrea en el cambio de orientación (configuración). Para solucionar esto en AndroidManifest.xml para su nodo:
En Android 3.0 y superior,
screenSize
aparentemente se requiere.Buena suerte
fuente
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
en su manifiesto. En cambio, aprenda cómo guardar y restaurar el estado, por ejemplo desde aquí: speakerdeck.com/cyrilmottier/…La mejor solución que encontré está a continuación:
onSavedInstanceState (): siempre se llama dentro del fragmento cuando la actividad se va a cerrar (mover la actividad de una a otra o cambiar la configuración). Entonces, si estamos llamando a varios fragmentos en la misma actividad, entonces tenemos que usar el siguiente enfoque:
Use OnDestroyView () del fragmento y guarde todo el objeto dentro de ese método. Luego OnActivityCreated (): compruebe que si el objeto es nulo o no (porque este método llama cada vez). Ahora restaure el estado de un objeto aquí.
¡Funciona siempre!
fuente
si está manejando los cambios de configuración en su actividad de fragmento especificada en el manifiesto de Android como este
entonces
onSaveInstanceState
no se invocará el fragmento y elsavedInstanceState
objeto siempre será nulo.fuente
No creo que
onSaveInstanceState
sea una buena solución. solo se usa para actividades que habían sido destruidas.Desde Android 3.0, Fragmen ha sido administrado por FragmentManager, la condición es: una actividad que mapea muchos fragmentos, cuando el fragmento se agrega (no reemplaza: se volverá a crear) en backStack, la vista se destruirá. cuando regrese al último, se mostrará como antes.
Así que creo que el fragmentManger y la transacción son lo suficientemente buenos como para manejarlo.
fuente
Usé un enfoque híbrido para fragmentos que contienen una vista de lista. Parece ser rentable ya que no reemplazo el fragmento actual, sino que agrego el nuevo fragmento y oculto el actual. Tengo el siguiente método en la actividad que aloja mis fragmentos:
Utilizo este método en mi fragmento (que contiene la vista de lista) cada vez que se hace clic / se toca un elemento de la lista (y, por lo tanto, necesito iniciar / mostrar el fragmento de detalles):
getFragmentTags()
devuelve una matriz de cadenas que uso como etiquetas para diferentes fragmentos cuando agrego un nuevo fragmento (vea eltransaction.add
método en eladdFragment
método anterior).En el fragmento que contiene la vista de lista, hago esto en su método onPause ():
Luego, en onCreateView del fragmento (en realidad en un método que se invoca en onCreateView), restauro el estado:
fuente
Al final, después de probar muchas de estas soluciones complicadas, ya que solo necesitaba guardar / restaurar un solo valor en mi Fragmento (el contenido de un EditText), y aunque podría no ser la solución más elegante, crear una referencia compartida y almacenar mi estado a mi me funciono
fuente
Una forma sencilla de mantener los valores de los campos en diferentes fragmentos de una actividad.
Cree las instancias de fragmentos y agregue en lugar de reemplazar y eliminar
Luego solo muestra y oculta los fragmentos en lugar de agregarlos y eliminarlos nuevamente
;
fuente
fuente