2011-05-03 16 views
13

EDITARfragmento extraño error de ciclo de vida

Así que parece que mi Fragment se retiene en la FragmentManager que trata de reiniciar la misma. Todavía no estoy seguro de por qué no se destruye con el Activity. En cuanto al mensaje de carga, esto se muestra cuando ListView no tiene un conjunto de adaptadores. Sin embargo, configuré los elementos del adaptador en onCreate y onResume, por lo que no estoy seguro de por qué se muestra esta pantalla de carga. Todavía está abierto a cualquier explicación de este comportamiento

original

estoy jugando un poco con fragmentos y se dio cuenta de un error raro que está apareciendo cuando cambie la orientación de la pantalla. Sin embargo, este error no debería estar sucediendo porque todos los datos se vuelven a crear en onCreate cuando se cambia la orientación de la pantalla. Además, el fragmento onResume() se llama dos veces después de la rotación. Aquí están mis pasos para crear el error y cómo el depurador está accionando las funciones.

  • Actividad: onCreate()
  • Actividad: onResume()
  • Fragmento: onResume()
  • pantalla de rotación
  • Actividad: onCreate()
  • Actividad: onResume()
  • Fragmento: onResume() (los elementos son nulos aunque Activity.onResume() los establezca)
  • Fragmento: onResume() (elementos no son nulas, por eso es este ser llamado dos veces?)

Después de este último fragmento onResume es golpeado, la tableta muestra una "Cargando ..." mensaje y el icono. ¿Por qué los datos no se muestran en la lista más? Mi sospecha es que onCreate está creando un segundo fragmento. El primer fragmento pierde sus datos debido a la orientación que destruye las vistas, el segundo fragmento obtiene los datos y la pantalla de carga es el primer fragmento sin elementos de datos y el segundo fragmento está oculto. Puedo estar equivocado. ¿Por qué no se destruyen todos los fragmentos cuando se gira la pantalla como Activity? Por favor, no critique el código a menos que sea para resolver este problema específico. Realmente no estoy haciendo una aplicación, estoy experimentando con la funcionalidad de fragmento. ¡Gracias!

Actividad Principal

private ArrayList<Object> items = new ArrayList<Object>(); 
private MyListFragment mylistFragment; 

public MainActivity() { 
    items.add("Hello"); 
    items.add("World"); 
    items.add("Goodbye"); 
} 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentManager fm = getFragmentManager(); 
    FragmentTransaction ft = fm.beginTransaction(); 

    mylistFragment = new MyListFragment(); 
    mylistFragment.setItems(items); 

    ft.add(R.id.container, mylistFragment); 
    ft.commit(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    mylistFragment.setItems(items); 
    mylistFragment.getListView().setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      Toast.makeText(MainActivity.this, ((TextView)view).getText(), Toast.LENGTH_LONG).show(); 
     } 

    }); 
} 

Lista Fragmento

private List<Object> items = null; 
private Boolean isSet = false; 

@Override 
public void onResume() { 
    super.onResume(); 
    if(!isSet && items != null) { 
     setListAdapter(new ArrayAdapter<Object>(getActivity(), R.layout.item, items)); 
     isSet = true; 
    } 
} 

public void setItems(List<Object> items) { 
    this.items = items; 
    if(this.isResumed()) { 
     setListAdapter(new ArrayAdapter<Object>(getActivity(), R.layout.item, items)); 
     isSet = true; 
    } else { 
     isSet = false; 
    } 
} 

Respuesta

5

El FragmentManager volverá a crear automáticamente el Fragment para mí. Sin embargo, los datos dentro de ellos deben ser reinicializados. Por lo tanto, mi código estaba creando un segundo fragmento. La pantalla de carga se debía a que el primer fragmento ya no tenía su adaptador de elementos y el segundo fragmento estaba oculto. Qué dolor de cabeza, casi creo que el FragmentManager debería destruir el Fragments para que pueda volver a crearlos con los datos que guardan.

+1

En este momento, sin embargo, no veo la respuesta demasiado clara ... ¿cómo acabaste la solución de este problema? Llegué a la misma conclusión que usted, pero no puedo encontrar una manera de resolver este problema. Es decir, cómo se matan los fragmentos antiguos y se usan los nuevos que se recrearon. – Maurycy

+0

Si desea deshacerse del Fragmento anterior y usar el nuevo, use la función FragmentTransaction.replace(). Entonces, el antiguo será reemplazado por el nuevo. Solo sé que los datos tendrán que ser recargados. – Spidy

0

Creo que esta es la razón por la cual en las diversas demos a través de Diane y otros ejemplos de google ...típicamente tienen alguna manera de ayudar a la inicialización a través de un método estático ... y setArguments.

IIRC, el material de creación de fragmentos llamará al constructor por defecto para crear, pero solo sabe cómo rellenar con los datos apropiados a través de setArguments. En el ejemplo del blog de desarrollo de Android ... la identificación se pasó de la lista de contactos al fragmento de detalles. Después de llamar a setParams, fragmentManager debería poder reanimarlo.

La documentación parece ser escasa sobre el tema y me gustaría estar haciendo las cosas bien, así que si ustedes tienen comentarios, les agradecería.

0

Parece que usar FragmentActivity de la biblioteca de soporte guarda y restaura la instancia automáticamente. Por lo tanto, solo haga sus transacciones de fragmento si savedInstanceState es null.

Por ejemplo, en sus FragmentActivity 's onCreate(), haga lo siguiente:

if(savedInstanceState == null){ 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction() 
     .replace(R.id.fragment_container, mFragment).commit(); //mFragment is your own defined fragment 
} 
Cuestiones relacionadas