In Android wird ein Fragment (sagen wir FragA
) zum Backstack hinzugefügt und ein anderes Fragment (sagen wir FragB
) wird nach oben gebracht. Jetzt kommt beim Zurückschlagen FragA
nach oben und das onCreateView()
heißt. Jetzt war ich FragA
in einem bestimmten Zustand, bevor ich darauf FragB
geschoben wurde.
Meine Frage ist, wie kann ich den FragA
vorherigen Zustand wiederherstellen ? Gibt es eine Möglichkeit, den Status zu speichern (wie beispielsweise in einem Bundle), und wenn ja, welche Methode sollte ich überschreiben?
quelle
onSaveInstanceState
wird nur aufgerufen, wenn die entsprechende Aktivität ebenfalls heruntergefahren wird.Fragmente
onSaveInstanceState(Bundle outState)
werden niemals aufgerufen, es sei denn, die Aktivität des Fragments nennt es sich selbst und angehängte Fragmente. Daher wird diese Methode erst aufgerufen, wenn etwas (normalerweise Rotation) die AktivitätSaveInstanceState
erzwingt und später wiederherstellt. Wenn Sie jedoch nur eine Aktivität und eine große Anzahl von Fragmenten darin haben (bei intensiver Nutzung vonreplace
) und die Anwendung nur in einer Ausrichtung ausgeführt wird, werden AktivitätenonSaveInstanceState(Bundle outState)
möglicherweise nicht lange aufgerufen.Ich kenne drei mögliche Problemumgehungen.
Der Erste:
Verwenden Sie die Argumente des Fragments, um wichtige Daten zu speichern:
Der zweite, aber weniger pedantische Weg - Variablen in Singletons halten
Die dritte - nicht
replace()
Fragment aberadd()
/show()
/hide()
sie statt.quelle
Fragment.onSaveInstanceState()
nie angerufen wurde. Speichern Sie einfach Ihre eigenen Daten im Argument, einschließlich der Elemente in der Listenansicht oder nur ihrer IDs (wenn Sie einen anderen zentralisierten Datenmanager haben). Die Position der Listenansicht muss nicht gespeichert werden - diese wurde gespeichert und automatisch wiederhergestellt.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
ist immer sonull
. Was ist das Problem?getArguments()
ist definitiv der richtige Weg, einschließlich verschachtelter Fragmente in einem ViewPager. Ich benutze 1 Aktivität und tausche viele Fragmente ein / aus, und das funktioniert perfekt. Hier ist ein einfacher Test, mit dem Sie jede vorgeschlagene Lösung überprüfen können: 1) Gehen Sie von Fragment A zu Fragment B; 2) zweimal die Ausrichtung des Geräts ändern; 3) Drücken Sie die Zurück-Taste am Gerät.setArguments(new Bundle());
alte Bundle aufgerufen und überschrieben. Stellen Sie also sicher, dass Sie das Fragment nur einmal erstellt haben, und verwenden Sie diese Instanz, anstatt jedes Mal ein neues zu erstellen.Beachten Sie nur, dass es ziemlich einfach ist, mit Fragmenten mit ViewPager zu arbeiten. Sie müssen nur diese Methode aufrufen :
setOffscreenPageLimit()
.Entsprechen Sie den Dokumenten:
Ähnliches Problem hier
quelle
Blasen Sie Ihre Ansicht einfach einmal auf.
Beispiel folgt:
}}
quelle
Fragment
bezieht sich auf seine Root-Ansicht wird das nicht tun. Während die Referenzierung durch einige GC-Root-Elemente , wie die globale statische Eigenschaft, eine Nicht-UI-Thread-Variable ist. EineFragment
Instanz ist keine GC-Wurzel, daher kann Müll gesammelt werden. Dies gilt auch für die Stammansicht.Ich habe mit einem ähnlichen Thema gearbeitet. Da ich wusste, dass ich häufig zu einem vorherigen Fragment zurückkehren würde, überprüfte ich, ob das Fragment
.isAdded()
wahr ist, und wenn ja, anstatt a zu tun, machetransaction.replace()
ich einfach atransaction.show()
. Dies verhindert, dass das Fragment neu erstellt wird, wenn es sich bereits auf dem Stapel befindet - es ist keine Speicherung des Status erforderlich.Eine andere Sache, die Sie beachten sollten, ist, dass dies zwar die natürliche Reihenfolge der Fragmente selbst beibehält, Sie jedoch möglicherweise immer noch die Aktivität selbst behandeln müssen, die bei einer Änderung der Ausrichtung (Konfiguration) zerstört und neu erstellt wird. So umgehen Sie dies in AndroidManifest.xml für Ihren Knoten:
In Android 3.0 und höher ist das
screenSize
anscheinend erforderlich.Viel Glück
quelle
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
in Ihr Manifest ein. Erfahren SieDie beste Lösung, die ich gefunden habe, ist unten:
onSavedInstanceState (): Wird immer innerhalb des Fragments aufgerufen, wenn die Aktivität beendet wird (Aktivität von einer zur anderen verschieben oder Konfigurationsänderungen vornehmen). Wenn wir also mehrere Fragmente für dieselbe Aktivität aufrufen, müssen wir den folgenden Ansatz verwenden:
Verwenden Sie OnDestroyView () des Fragments und speichern Sie das gesamte Objekt in dieser Methode. Dann OnActivityCreated (): Überprüfen Sie, ob das Objekt null ist oder nicht (da diese Methode jedes Mal aufruft). Stellen Sie nun hier den Status eines Objekts wieder her.
Es funktioniert immer!
quelle
Wenn Sie die Konfigurationsänderungen in Ihrer Fragmentaktivität behandeln, die im Android-Manifest wie folgt angegeben sind
dann wird das
onSaveInstanceState
des Fragments nicht aufgerufen und dassavedInstanceState
Objekt ist immer null.quelle
Ich denke nicht, dass
onSaveInstanceState
es eine gute Lösung ist. es wird nur für Aktivitäten verwendet, die zerstört wurden.Ab Android 3.0 wurde Fragmen von FragmentManager verwaltet. Die Bedingung lautet: Eine Aktivität, die Manny-Fragmente zuordnet. Wenn das Fragment in backStack hinzugefügt (nicht ersetzt: neu erstellt) wird, wird die Ansicht gespeichert. Wenn Sie zum letzten zurückkehren, wird es wie zuvor angezeigt.
Ich denke also, dass der fragmentManger und die Transaktion gut genug sind, um damit umzugehen.
quelle
Ich habe einen hybriden Ansatz für Fragmente verwendet, die eine Listenansicht enthalten. Es scheint performant zu sein, da ich das aktuelle Fragment nicht ersetze, sondern das neue Fragment hinzufüge und das aktuelle ausblende. Ich habe die folgende Methode in der Aktivität, die meine Fragmente hostet:
Ich verwende diese Methode in meinem Fragment (das die Listenansicht enthält), wenn auf ein Listenelement geklickt / getippt wird (und daher muss ich das Detailfragment starten / anzeigen):
getFragmentTags()
Gibt ein Array von Zeichenfolgen zurück, die ich als Tags für verschiedene Fragmente verwende, wenn ich ein neues Fragment hinzufüge (siehetransaction.add
Methode inaddFragment
Methode oben).In dem Fragment, das die Listenansicht enthält, mache ich dies in der onPause () -Methode:
Dann stelle ich in onCreateView des Fragments (tatsächlich in einer Methode, die in onCreateView aufgerufen wird) den Status wieder her:
quelle
Am Ende, nachdem ich viele dieser komplizierten Lösungen ausprobiert hatte, musste ich nur einen einzelnen Wert in meinem Fragment (den Inhalt eines EditText) speichern / wiederherstellen, und obwohl dies möglicherweise nicht die eleganteste Lösung ist, eine SharedPreference erstellen und meinen Status speichern dort hat für mich gearbeitet
quelle
Eine einfache Möglichkeit, die Werte von Feldern in verschiedenen Fragmenten einer Aktivität zu speichern
Erstellen Sie die Instanzen von Fragmenten und fügen Sie sie hinzu, anstatt sie zu ersetzen und zu entfernen
Zeigen Sie dann einfach die Fragmente an und verbergen Sie sie, anstatt sie erneut hinzuzufügen und zu entfernen
;;
quelle
quelle