So bestimmen Sie das aus dem Backstack wiederhergestellte Fragment

Lesezeit: 5 Minuten

Benutzer-Avatar
DVD

Suche seit einiger Zeit vergeblich nach diesem Problem:

Wie kann festgestellt werden, dass das Fragment aus dem Backstack wiederhergestellt wird? Ich verwende die Kompatibilitätsbibliothek und ein ListFragment in einer FragmentActivity. Wenn ein Element innerhalb von ListFragment ausgewählt wird, wird ein neues Fragment gestartet, um das ListFragment zu ersetzen.

Mir ist aufgefallen, dass beim Anhalten der FragmentActivity der onSaveInstanceState des Fragments aufgerufen wird. Aber wenn das Fragment über FragmentTransaction in den Backstack gestellt wird, wird onSaveInstanceState nicht aufgerufen, dann werden die Lebenszyklusmethoden onCreateView und onActivityCreated mit null savedInstanceState Bundle aufgerufen.

Ich frage dies, weil ich einige Daten laden möchte, wenn das Fragment erstellt oder wiederhergestellt wird, aber nicht, wenn der Benutzer per zurückkommt. Backstack.

Ich habe mir angesehen, wie man überprüft, ob Fragment aus einem Backstack wiederhergestellt wurde? möchte aber weitere Details hinzufügen, in der Hoffnung, dass dies zu einer Antwort anregen würde.

Edit: gerade bemerkt http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle)
sagt

Beachten Sie jedoch: Diese Methode kann jederzeit vor onDestroy() aufgerufen werden. Es gibt viele Situationen, in denen ein Fragment größtenteils abgerissen wird (z. B. wenn es auf dem Backstack platziert wird, ohne dass die Benutzeroberfläche angezeigt wird), aber sein Zustand wird nicht gespeichert, bis seine besitzende Aktivität seinen Zustand tatsächlich speichern muss.

onSaveInstanceState kommt also definitiv nicht in Frage …

  • Als kleines Update zu dieser Frage vermute ich immer mehr, dass es an den Macken der Kompatibilitätsbibliothek liegt. Ich habe noch nicht versucht, einen Testfall auf 3.0+-Geräten auszuführen, werde es noch einmal überprüfen, wenn ich es tue.

    – DVD

    20. April 2012 um 18:24 Uhr

  • warum rufen Sie nicht Ihren Server auf, um die Daten zu laden onCreate(). Vielleicht lindert das Ihre Beschwerden. Ich glaube, diese spezielle Methode wird nicht aufgerufen, wenn ein Fragment aus dem Backstack wiederhergestellt wird.

    – Abhijit

    4. Juni 2013 um 22:08 Uhr


Ich denke, der einfachste Weg ist dies zum Beispiel in der Methode onViewCreated () :

if (savedInstanceState == null && !mAlreadyLoaded) {
    mAlreadyLoaded = true;

    // Do this code only first time, not after rotation or reuse fragment from backstack
}

Denn wenn Android ein Fragment auf den Backstack legt, zerstört es nur seine Ansicht, beendet aber nicht die Instanz selbst, sodass mAlreadyLoaded immer noch wahr ist, wenn das Fragment aus dem Backstack wiederhergestellt wird.

  • Dies ist die richtige Antwort, um festzustellen, ob die Fragmentinstanz aus dem Backstack wiederhergestellt wurde. Ich hatte endlich die Gelegenheit, dieses Thema erneut zu besuchen und den Quellcode zu FragmentManager in der Version 13 der Support-v4-Bibliothek zu lesen. Die Fragmentinstanz wird, wie von ATom gesagt, beim Hinzufügen zum Backstack beibehalten. Das Setzen und Überprüfen eines Flags in onViewCreated funktioniert also.

    – DVD

    20. Juni 2013 um 17:49 Uhr

  • Dies funktioniert nur, wenn Sie angerufen haben setRetainInstance(true)was nicht immer möglich ist.

    – Benoît Duffez

    22. Juni 2013 um 15:17 Uhr

  • @BenoitDuffez Ich glaube, das ist nur notwendig, wenn Sie mit a arbeiten Fragment Deren FragmentTransaction wurde nicht zum Backstack hinzugefügt. Wenn die Transaktion zum Backstack hinzugefügt wurde, dann das Fragment wird automatisch beibehalten (dh seine onDestroy wird nicht angerufen). Aus den Dokumenten. Wenn Sie es nicht zum Backstack hinzufügen, müssen Sie anrufen setRetainInstance() wie du gesagt hast, wenn du willst, dass es nicht zerstört wird.

    – Toni Chan

    21. Oktober 2014 um 22:01 Uhr

  • Dort sind einige Problemumgehungen die verwendet werden können, um Anrufe zu vermeiden setRetainInstance() und dennoch feststellen, ob das Fragment aus dem Backstack wiederhergestellt ist.

    – Benoît Duffez

    21. Oktober 2014 um 23:34 Uhr


getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() {    
            public void onBackStackChanged() {
                Log.i(TAG, "back stack changed ");
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0){
                                   // block where back has been pressed. since backstack is zero.
                }
            }
        });

Verwenden Sie diesen addOnBackStackChangedListener.

  • Ich habe das gerade versucht, das Problem ist, dass onBackStackChanged aufgerufen wird, nachdem die Methoden des Fragment-Lebenszyklus aufgerufen wurden. Was ich tun möchte, ist: Daten laden, wenn das Fragment zum ersten Mal erstellt wird, Daten speichern und bei Bedarf wiederherstellen (kein Neuladen). Dies wurde durch bedingtes Laden/Wiederherstellen in onActivityCreated erreicht. Wenn das Fragment durch Öffnen des Backstacks wiederhergestellt wird, laden Sie die Daten nicht neu. Selbst wenn ich ein Flag in onBackStackChanged setze, sehen die Lebenszyklusmethoden es nicht.

    – DVD

    27. Oktober 2011 um 18:36 Uhr


Wenn ein Fragment in den Back-Stack geht onDestroyView() genannt. Nicht onDestroy().

Und wenn ein Fragment aus dem Back-Stack springt onCreateView() genannt. Nicht onCreate().

Also füge ein hinzu boolean mIsRestoredFromBackstack zu fragmentieren und folgen Sie wie folgt:

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    mIsRestoredFromBackstack = false;
}

@Override
public void onResume()
{
    super.onResume();
    if(mIsRestoredFromBackstack)
    {
        // The fragment restored from backstack, do some work here!
    }
}

@Override
public void onDestroyView()
{
    super.onDestroyView();
    mIsRestoredFromBackstack = true;
}

  • onDestroyView wird vom Sperren des Bildschirms aufgerufen, also wird meine Aktion zweimal aufgerufen, nachdem ich vom Backstack zurückgekommen bin

    – ldrrp

    13. Februar 2018 um 20:34 Uhr

  • „Und wenn ein Fragment aus dem hinteren Stapel springt onCreateView() angerufen.” Nun, nein.

    – Farid

    29. Februar 2020 um 8:09 Uhr

Benutzer-Avatar
Giorgos Kylafas

GROSSE BEARBEITUNG: 15. Oktober 2013

Die vorherige Erklärung (unten als Referenz aufbewahrt) schlägt fehl, wenn die Anwendung in den Hintergrund gestellt und wieder in den Vordergrund gebracht wird.

Stattdessen ist es besser, die aktuelle Größe des Backstacks mit derjenigen zu vergleichen, als das Fragment erstellt und in den Backstack gelegt wurde.


Schauen Sie sich Abbildung 2 in genau an http://developer.android.com/guide/components/fragments.html#Creating

Was diese Abbildung Ihnen sagt, ist, dass, wenn ein Fragment aus dem Backstack wiederhergestellt wird, sein onCreate() nicht aufgerufen wird, während es sein onCreateView() ist.


Vielleicht möchten Sie so etwas tun:

public class MyFragment extends Fragment {
    int mBackStackSize = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBackStackSize = getFragmentManager().getBackStackEntryCount();
    }

    public boolean isRestoredFromBackstack() {
        return mBackStackSize > getFragmentManager().getBackStackEntryCount();
    }
}

Benutzer-Avatar
Inc

Wenn Sie ein Fragment zum Backstack hinzugefügt haben und es nach einigen Manipulationen mit fragmentTransaction.hide(fragment) ausblenden und es dann aus dem Backstack wiederherstellen, wie fragmentTransaction.show(fragmentManager.findFragmentByTag(fragment.getName())); Sie können onHiddenChanged (boolean hidden) überschreiben

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}

  • Genau danach habe ich gesucht. Vielen Dank! Beachten Sie nur, dass es sein sollte if (!hidden) {

    – Crubio

    19. April 2017 um 16:05 Uhr

Benutzer-Avatar
Alex Korovyansky

In einigen Fällen können Sie verwenden ist sichtbar Methode zu verstehen, ist es das erste Zeigen eines Fragments oder wird es aus dem Backstack wiederhergestellt.

  • Genau danach habe ich gesucht. Vielen Dank! Beachten Sie nur, dass es sein sollte if (!hidden) {

    – Crubio

    19. April 2017 um 16:05 Uhr

1214340cookie-checkSo bestimmen Sie das aus dem Backstack wiederhergestellte Fragment

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy