2013-07-22 95 views
12

Sono davvero confuso con lo stato interno di un frammento. Possiedo un'attività che trattiene un solo frammento in una sola volta e lo sostituisce se viene visualizzato un altro frammento. Dai documenti onSaveInstanceState si chiama SOLO se viene richiamata l'attività onSaveInstanceState (che nel mio caso non viene chiamata).Come funziona `onViewStateRestored` da Fragments?

Se interrompo il mio frammento, memorizzerò il suo stato all'interno di un Singleton (sì, so che odio anche Singletons, ma non era mia intenzione farlo). Quindi devo ricreare l'intero ViewHirarchy, creare nuove viste (utilizzando la parola chiave new), ripristinarne lo stato e restituirle in onCreateView. Ho anche una casella di controllo all'interno di questa vista dalla quale faccio esplicitamente NON voglio memorizzare il suo stato.

Tuttavia il FragmentManager vuole essere "intelligente" e chiede onViewStateRestored con un fascio Non mi sono mai creato, e "ripristina" lo stato del vecchio CheckBox e lo applica a mia nuova casella di controllo. Questo solleva così tante domande:

Posso controllare il pacchetto da onViewStateRestored?

In che modo FragmentManager assume lo stato di un CheckBox (probabilmente con raccolta dei dati inutili) e lo applica a quello nuovo?

Perché solo salvare lo stato della casella di controllo (non di TextViews ??)

Quindi, per riassumere: Come funziona onViewStateRestored lavoro?

nota che sto utilizzando Fragmentv4, in modo che nessun API> 17 richiesto per onViewStateRestored

risposta

17

Beh, a volte frammenti possono ottenere un po 'di confusione, ma dopo un po' si abitua a loro, e sapere che sono il vostro amici dopotutto.

Se sul metodo onCreate() del proprio frammento, si esegue: setRetainInstance (true); Lo stato visibile dei tuoi punti di vista verrà mantenuto, altrimenti non lo sarà.

Supponiamo che un frammento chiamato "f" di classe F, il suo ciclo di vita sarebbe andata in questo modo: - Quando un'istanza/fissaggio/mostrarla, questi sono i metodi del f che sono chiamati, in questo ordine:

F.newInstance(); 
F(); 
F.onCreate(); 
F.onCreateView(); 
F.onViewStateRestored; 
F.onResume(); 

A questo punto, il tuo frammento sarà visibile sullo schermo. Supponiamo che il dispositivo sia ruotato, quindi le informazioni sul frammento devono essere preservate, questo è il flusso di eventi attivati ​​dalla rotazione:

F.onSaveInstanceState(); //save your info, before the fragment is destroyed, HERE YOU CAN CONTROL THE SAVED BUNDLE, CHECK EXAMPLE BELLOW. 
F.onDestroyView(); //destroy any extra allocations your have made 
//here starts f's restore process 
F.onCreateView(); //f's view will be recreated 
F.onViewStateRestored(); //load your info and restore the state of f's view 
F.onResume(); //this method is called when your fragment is restoring its focus, sometimes you will need to insert some code here. 


//store the information using the correct types, according to your variables. 
@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putSerializable("foo", this.foo); 
    outState.putBoolean("bar", true); 
} 

@Override 
public void onViewStateRestored(Bundle inState) { 
    super.onViewStateRestored(inState); 
    if(inState!=null) { 
     if (inState.getBoolean("bar", false)) { 
      this.foo = (ArrayList<HashMap<String, Double>>) inState.getSerializable("foo"); 
     } 
    } 

}