Ho trovato molti casi di una domanda simile su SO ma purtroppo nessuna risposta soddisfa i miei requisiti.
Ho diversi layout per verticale e orizzontale e sto usando back stack, che mi impedisce sia di usare setRetainState()che trucchi usando le routine di modifica della configurazione.
Mostro determinate informazioni all'utente in TextViews, che non vengono salvate nel gestore predefinito. Quando ho scritto la mia applicazione esclusivamente utilizzando Attività, ha funzionato bene:
TextView vstup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.whatever);
vstup = (TextView)findViewById(R.id.whatever);
/* (...) */
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putCharSequence(App.VSTUP, vstup.getText());
}
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
vstup.setText(state.getCharSequence(App.VSTUP));
}
Con Fragments, questo funziona solo in situazioni molto specifiche. In particolare, ciò che si rompe in modo orribile è la sostituzione di un frammento, lo mette nella pila posteriore e quindi ruota lo schermo mentre viene mostrato il nuovo frammento. Da quello che ho capito, il vecchio frammento non riceve una chiamata a onSaveInstanceState()quando viene sostituito, ma rimane in qualche modo collegato al Activitye questo metodo viene chiamato più tardi quando Viewnon esiste più, quindi cerca uno qualsiasi dei miei TextViewrisultati in a NullPointerException.
Inoltre, ho scoperto che mantenere il riferimento al mio TextViewsnon è una buona idea con Fragments, anche se è stato OK con Activity. In tal caso, in onSaveInstanceState()realtà salva lo stato ma il problema riappare se ruoto lo schermo due volte quando il frammento è nascosto, poiché onCreateView()non viene chiamato nella nuova istanza.
Ho pensato di salvare lo stato in onDestroyView()in qualche Bundleelemento membro della classe di tipo (in realtà più dati, non solo uno TextView) e risparmio che in onSaveInstanceState()ma ci sono altri inconvenienti. In primo luogo, se il frammento è attualmente mostrato, l'ordine di chiamare le due funzioni è invertito, quindi dovrei tenere conto di due diverse situazioni. Ci deve essere una soluzione più pulita e corretta!