544 Stimmen

Wie speichert man den Instanzzustand von Fragments korrekt im Back-Stack?

Ich habe viele Instanzen einer ähnlichen Frage auf SO gefunden, aber leider entspricht keine Antwort meinen Anforderungen.

Ich habe verschiedene Layouts für Hochformat und Querformat und benutze den Back-Stack, was sowohl die Verwendung von setRetainState() als auch Tricks mit Konfigurationsänderungsroutinen verhindert.

Ich zeige bestimmte Informationen dem Benutzer in TextViews an, die nicht im Standard-Handler gespeichert werden. Als ich meine Anwendung ausschließlich unter Verwendung von Activities geschrieben habe, hat Folgendes gut funktioniert:

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));
}

Mit Fragments funktioniert dies nur in sehr spezifischen Situationen. Insbesondere wird es furchtbar durcheinander, wenn ein Fragment ersetzt, in den Back-Stack gelegt und dann der Bildschirm gedreht wird, während das neue Fragment angezeigt wird. Soweit ich verstanden habe, erhält das alte Fragment keinen Aufruf von onSaveInstanceState() bei einem Ersatz, bleibt aber irgendwie mit der Activity verbunden und diese Methode wird später aufgerufen, wenn seine View nicht mehr existiert, sodass das Suchen nach einem meiner TextViews zu einer NullPointerException führt.

Außerdem habe ich festgestellt, dass es keine gute Idee ist, Referenzen auf meine TextViews mit Fragments zu behalten, auch wenn es mit Activitys in Ordnung war. In diesem Fall speichert onSaveInstanceState() tatsächlich den Zustand, aber das Problem tritt wieder auf, wenn ich den Bildschirm zweimal drehe, wenn das Fragment verborgen ist, da sein onCreateView() im neuen Fall nicht aufgerufen wird.

Ich dachte daran, den Zustand in onDestroyView() in ein Bundle-Artiges Klassenmember-Element zu speichern (es handelt sich tatsächlich um mehr Daten, nicht nur eine TextView) und dieses in onSaveInstanceState() zu speichern, aber es gibt andere Nachteile. Vor allem, wenn das Fragment tatsächlich angezeigt wird, wird die Reihenfolge der Aufrufe der beiden Funktionen umgekehrt, sodass ich zwei verschiedene Situationen berücksichtigen müsste. Es muss eine sauberere und korrekte Lösung geben!

0voto

amir Punkte 183

Verwendung von :

  private var mData: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState != null) {
            mData= savedInstanceState.getString("Data")
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("mData", Data)
    }

-9voto

Nilesh Savaliya Punkte 616
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(currentFragment);
ft.add(R.id.content_frame, newFragment.newInstance(context), "Profil");
ft.addToBackStack(null);
ft.commit();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X