2012-05-17 16 views
13

Estoy desarrollando una aplicación que básicamente tiene una barra de acciones. Cuando se inicia mi aplicación, la actividad crea los fragmentos y los adjunta a cada pestaña, de modo que cuando cambio obtengo diferentes vistas.Fragmentos de Android reconstruidos en el cambio de orientación

Los problemas surgen cuando intento girar el dispositivo. Después de una lucha, me di cuenta que Android recrea de forma automática los fragmentos añadidos anteriormente como esto:

SummaryFragment.onCreate(Bundle) line: 79 
FragmentManagerImpl.moveToState(Fragment, int, int, int) line: 795 
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1032 
FragmentManagerImpl.moveToState(int, boolean) line: 1014  
FragmentManagerImpl.dispatchCreate() line: 1761 
DashboardActivity(Activity).onCreate(Bundle) line: 864 
... 

y luego volver a crear los fragmentos como de costumbre. Así que tengo los fragmentos "reales" que espero que funcionen correctamente y sus contrapartes "ocultas" creadas por Android que hacen que mi aplicación se cuelgue. ¿Cómo puedo evitar este comportamiento? Ya traté de llamar a setRetainInstance (false) en SummaryFragment.

Gracias

Respuesta

35

Es necesario comprobar para un savedInstanceState [editar: en su actividad los padres], y si existe, no crean sus fragmentos.

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    if (savedInstanceState == null) { 
     // Do your oncreate stuff because there is no bundle 
    } 
// Do stuff that needs to be done even if there is a saved instance, or do nothing 
} 
+1

no estoy seguro si es el mismo problema que tenía OP, pero esto fue increíblemente útil para mí. Gracias. – ssmy

+0

Muchas gracias @Barak única solución funcionó después de una semana –

0

Si usted tiene la interfaz de usuario similar (no hay archivos específicos de diseño en tierra) para ambas orientaciones se pueden establecer android:configChanges="keyboardHidden|orientation" a la actividad en el archivo de manifiesto.

Si no proporciona, por favor, el código fuente donde está agregando los fragmentos a las pestañas, e intentaré ayudarlo con las mejoras.

+0

Parcialmente resuelto con su respuesta. Como la mayoría del dibujo se realiza dinámicamente, elimino todas las vistas y las relatifico según la nueva orientación. Honestamente, no creo que sea una solución limpia, pero no puedo evitar que el sistema cree salvajemente fragmentos para mí ... – Luke47

+0

Esto me ayudó porque me olvidé de actualizar mis archivos de diseño después de que cambie el retrato. Me ha conseguido unas 5 veces ahora. – buster

+3

Ocurrirán cosas desagradables al enchufar el dispositivo en una base para automóvil, o en un televisor, o cualquier otro cambio de configuración: los fragmentos seguirán siendo recreados. android: configChanges es malo, a menos que realmente sepas lo que estás haciendo. – personne3000

0

Al crear su actividad, verifique que no exista ya. Si existe, no hagas nada ... Android lo volverá a crear para ti.

private void initFragment() { 
     FragmentManager fragMgr = getSupportFragmentManager(); 
     if (fragMgr.findFragmentByTag(LEADERBOARD_FRAG_TAG) != null) { return; } 
     frag = new HdrLeaderboardFragment(); 
     FragmentTransaction ft = fragMgr.beginTransaction(); 
     ft.replace(R.id.leaderboard_fragment_wrapper, frag, LEADERBOARD_FRAG_TAG); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
     ft.commit(); 
    } 
+1

Al hacerlo, agrega dos fragmentos ... el que ya tenía (en la forma que sugeriste) más otro que literalmente me está volviendo loco. Habría sido tan fácil restablecer FragmentManager entre cambios de orientación ... – Luke47

0

No estoy seguro de si hay una solución mejor, pero esto es lo que hice en el último programa.

Cuando el sistema crea automáticamente un fragmento en el cambio de orientación y si desea hacer un seguimiento de ellos en la actividad del host, tómelos en el método OnAttachFragment() de la actividad del host. Y obtienen los argumentos por defecto, por lo que puede usarlos para descubrir qué fragmento es.

public void onAttachFragment(Fragment fragment) { 
    super.onAttachFragment(fragment); 
    if (fragment != null) { 
     if(fragment.getArguments() != null) { 
      switch (fragment.getArguments().getString(ARG_PARAM1)) { 
       case FragmentATag: 
        if (myFragmentA != fragment) { 
         myFragmentA = (FragmentA) fragment; 
        }      
        break; 
       case FragmentBTag: 
        if (myFragmentB != fragment) { 
         myFragmentB = (FragmentB) fragment; 
        }       
        break;     
      } 
     } 
    } 
    } 
Cuestiones relacionadas