2012-08-27 9 views
6

Mi aplicación Android tiene un ActionBar que cambia que Fragment ocupa un cierto FrameLayout. Estoy tratando de usar onSaveInstanceState para guardar el estado de un Fragmento cuando se cambia la pestaña, para que pueda ser recuperado en onCreateView.Separar un Fragmento que no desencadena onSaveInstanceState()

El problema es, onSaveInstanceState Nunca se llama. Se llaman los métodos FragmentonDestroyView y onCreateView, pero el Bundle suministrado a onCreateView permanece nulo.

¿Puede alguien explicarme cuándo se llama realmente onSaveInstanceState, cómo puedo asegurarme de que se llama cuando se cambian las pestañas, o las mejores prácticas para guardar y restablecer el estado de un Fragment cuando se desconecta y se vuelve a conectar?

Fragmento:

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.event_log, container, false); 

    // Retrieve saved state 
    if (savedInstanceState != null){ 
     System.out.println("log retrieved"); 
    } else { 
     System.out.println("log null"); 
    } 

    return view; 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    System.out.println("log saved"); 
    super.onSaveInstanceState(outState); 
    // more code 
} 

Actividad:

/** 
* Detach the current Fragment, because another one is being attached. 
*/ 
@Override 
public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
    if (tab.getText().equals(getString(R.string.tab_events))){ 
     if (frEventLog != null) { 
      ft.detach(frEventLog); 
    } 
} 
+0

copia eventual de http://stackoverflow.com/questions/8503629/fragments-onsaveinstancestate-never-called – DeeV

+0

lo que es frEventLog? –

Respuesta

8

Fragment#onSaveInstanceState sólo se invoca cuando el Activity anfitrión de la Fragment es destruida y hay una posibilidad de que pueda volver a la misma actividad y la fragmento todavía se agrega al FragmentManager. El caso más común sería la rotación de pantalla.

Creo que su Fragment también tendrá que hacer setRetainInstance(true) en onCreate por ejemplo. Sin embargo, no estoy seguro acerca de ese punto.

También debe ver este método se llama cuando se presiona el botón de inicio, por ejemplo. Eso destruirá la actividad, pero puede volver a ella utilizando la lista de tareas, por ejemplo.

Si solo detach() el fragmento de todo lo que necesita hacer para recuperarlo es solicitándolo al FragmentManager.

Hay dos ejemplos que usted debe echar un vistazo a:

ActionBar FragmentTabs y TabHost FragmentTabs

El ejemplo TabHost utiliza

ft.add(containerId, fragment, tag); 
// later 
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag); 

para encontrar los casos de anterioridad añade Fragment s, trabaja hasta que se remove() a Fragment


Con respecto a onCreateView/onDestroyView: Se llama una vez que un fragmento se desprende porque la próxima vez que lo conecte necesita crear un nuevo View. Tenga en cuenta que Fragment#onDetached() no se invoca cuando detach() el fragmento, ya que todavía se une a la Activity. Solo está separado de la jerarquía de vistas.


Hay otro buen ejemplo de cómo conservar el estado fragmento/cómo utilizar fragmentos para conservar el estado en el entrenamiento Android - Caching Bitmaps.

Ese ejemplo le falta una línea crítica aunque:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { 
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG); 
    if (fragment == null) { 
     fragment = new RetainFragment(); 
     fm.beginTransaction().add(fragment, TAG).commit(); // << add this 
    } 
    return fragment; 
} 
+0

Gracias por su respuesta. Tenía la impresión de que el uso de setRetainInstance (verdadero) requeriría bastante memoria, ya que significaría almacenar las pestañas en lugar de destruirlas y volverlas a crear, pero lo probaré. ¿Debo obtener mis Fragmentos a través del FragmentManager o puedo mantener una referencia a ellos en un campo? – Dan

+0

No necesita una referencia en absoluto. FragmentManager tiene referencias a ellos, pero puede agregar uno si no agrega pérdidas de memoria. La intensidad de la memoria depende de la cantidad que uses en tus fragmentos, que puede ser cercana a 0 si lo haces bien. – zapl

+0

Creo que ya ordené esto con la ayuda de tu primer ejemplo. Mi problema era que tenía un código en el método onActivityCreated() del Fragment que esencialmente lo estaba restableciendo, ya que no sabía que este método se ejecutaría más de una vez. – Dan

Cuestiones relacionadas