Was ist der Unterschied zwischen FragmentPagerAdapter
und FragmentStatePagerAdapter
?
Über den FragmentPagerAdapter
Google-Leitfaden heißt es:
Diese Version des Pagers eignet sich am besten für den Fall, dass eine Handvoll normalerweise statischerer Fragmente durchlaufen werden müssen, z. B. eine Reihe von Registerkarten. Das Fragment jeder Seite, die der Benutzer besucht, wird gespeichert, obwohl die Ansichtshierarchie möglicherweise zerstört wird, wenn sie nicht sichtbar ist. Dies kann dazu führen, dass eine erhebliche Menge an Speicher verwendet wird, da Fragmentinstanzen eine beliebige Menge an Zustand beibehalten können. Berücksichtigen Sie bei größeren Seitenmengen
FragmentStatePagerAdapter
.
Und über FragmentStatePagerAdapter
:
Diese Version des Pagers ist nützlicher, wenn eine große Anzahl von Seiten vorhanden ist und eher wie eine Listenansicht funktioniert. Wenn Seiten für den Benutzer nicht sichtbar sind, wird möglicherweise das gesamte Fragment zerstört, wobei nur der gespeicherte Status dieses Fragments beibehalten wird. Dies ermöglicht es dem Pager, mit jeder besuchten Seite viel weniger Speicher zu belegen als
FragmentPagerAdapter
auf Kosten eines möglicherweise höheren Overheads beim Wechseln zwischen Seiten.
Ich habe also nur 3 Fragmente. Alle sind jedoch separate Module mit einer großen Datenmenge.
Fragment1
behandelt einige Daten (die Benutzer eingeben) und übergibt sie über Aktivität an Fragment2
, was nur eine einfache ist ListFragment
. Fragment3
ist auch ein ListFragment
.
Meine Fragen sind also : Welchen Adapter soll ich verwenden? FragmentPagerAdapter
oder FragmentStatePagerAdapter
?
quelle
FragmentPagerAdapter
undFragmentStatePagerAdapter
aber was istFragmentStateAdapter
?Antworten:
Wie die Dokumente sagen, denken Sie so darüber nach. Wenn Sie eine Anwendung wie einen Buchleser ausführen, möchten Sie nicht alle Fragmente gleichzeitig in den Speicher laden. Sie möchten laden und zerstören,
Fragments
während der Benutzer liest. In diesem Fall werden Sie verwendenFragmentStatePagerAdapter
. Wenn Sie nur 3 "Registerkarten" anzeigen, die nicht viele schwere Daten (wieBitmaps
) enthalten, ist diesFragmentPagerAdapter
möglicherweise gut für Sie geeignet. Beachten Sie außerdem, dassViewPager
standardmäßig 3 Fragmente in den Speicher geladen werden. Der erste, denAdapter
Sie erwähnen, kann dieView
Hierarchie zerstören und bei Bedarf neu laden, der zweiteAdapter
speichert nur den Status vonFragment
und zerstört ihn vollständig. Wenn der Benutzer dann zu dieser Seite zurückkehrt, wird der Status abgerufen.quelle
FragmentPagerAdapter
, es zu benutzen.FragmentPagerAdapter
dass das Wechseln zwischen Fragmenten viel schneller sein kann, da die tatsächlichenFragment
Objekte nicht jedes Mal neu erstellt werden müssen. Andererseits würde dies dazu führen, dass mehr Speicher benötigt wird, der die Fragmentobjekte im Speicher hält.viewPager.setOffscreenPageLimit(2)
.FragmentPagerAdapter
speichert das gesamte Fragment im Speicher und kann den Speicheraufwand erhöhen, wenn eine große Anzahl von Fragmenten in verwendet wirdViewPager
.Im Gegensatz zu seinem Geschwister
FragmentStatePagerAdapter
speichert es nur den gespeicherten Instanzstatus von Fragmenten und zerstört alle Fragmente, wenn sie den Fokus verlieren.Daher
FragmentStatePagerAdapter
sollte verwendet werden, wenn dynamische Fragmente wie Fragmente mit Widgets verwendet werden müssen, da deren Daten in dersavedInstanceState
Datei gespeichert werden können. Dies wirkt sich auch dann nicht auf die Leistung aus, wenn eine große Anzahl von Fragmenten vorhanden ist.Im Gegensatz dazu sollte sein Geschwister
FragmentPagerAdapter
verwendet werden, wenn wir das gesamte Fragment im Speicher speichern müssen.Wenn ich sage, dass das gesamte Fragment im Speicher bleibt, bedeutet dies, dass seine Instanzen nicht zerstört werden und einen Speicheraufwand verursachen würden. Daher wird empfohlen,
FragmentPagerAdapter
nur zu verwenden , wenn eine geringe Anzahl von Fragmenten für vorhanden istViewPager
.Es wäre sogar noch besser, wenn die Fragmente statisch wären, da sie keine große Anzahl von Objekten enthalten würden, deren Instanzen gespeichert würden.
Um genauer zu sein,
FragmentStatePagerAdapter:
Mit
FragmentStatePagerAdapter
wird Ihr nicht benötigtes Fragment zerstört. Eine Transaktion wird festgeschrieben, um das Fragment vollständig aus Ihren Aktivitäten zu entfernenFragmentManager
.Der Status in
FragmentStatePagerAdapter
ergibt sich aus der Tatsache, dass die FragmenteBundle
ab demsavedInstanceState
Zeitpunkt der Zerstörung gespeichert werden. Wenn der Benutzer zurück navigiert, wird das neue Fragment unter Verwendung des Status des Fragments wiederhergestellt.FragmentPagerAdapter:
Im Vergleich
FragmentPagerAdapter
macht nichts dergleichen. Wenn das Fragment nicht mehr benötigt wird.FragmentPagerAdapter
ruftdetach(Fragment)
die Transaktion stattremove(Fragment)
.Dadurch wird die Ansicht des Fragments zerstört, die Instanz
FragmentManager
des Fragments bleibt jedoch in der .iv. Die in der erstellten FragmenteFragmentPagerAdapter
werden also niemals zerstört.quelle
Hier ist ein Protokolllebenszyklus jedes Fragments, in
ViewPager
dem 4 Fragmente und enthalten sindoffscreenPageLimit = 1 (default value)
FragmentStatePagerAdapter
Gehe zu Fragment1 (Aktivität starten)
Gehe zu Fragment2
Gehe zu Fragment3
Gehe zu Fragment4
FragmentPagerAdapter
Gehe zu Fragment1 (Aktivität starten)
Gehe zu Fragment2
Gehe zu Fragment3
Gehe zu Fragment4
Fazit :
FragmentStatePagerAdapter
Rufen Sie an,onDestroy
wenn das Fragment überwunden ist, ohne dies zuoffscreenPageLimit
tunFragmentPagerAdapter
.Hinweis : Ich denke, wir sollten
FragmentStatePagerAdapter
für eineViewPager
Seite mit viel Seite verwenden, da dies für die Leistung gut ist.Beispiel für
offscreenPageLimit
:Wenn wir zu Fragment3 gehen, wird Fragment1 (oder Fragment5, falls vorhanden) zerstört, weil
offscreenPageLimit = 1
. Wenn wir einstellenoffscreenPageLimit > 1
, wird es nicht zerstören.Wenn wir in diesem Beispiel festlegen
offscreenPageLimit=4
, gibt es keinen Unterschied zwischen der VerwendungFragmentStatePagerAdapter
oderFragmentPagerAdapter
weil Fragment niemals aufruftonDestroyView
undonDestroy
wenn wir die Registerkarte wechselnGithub Demo hier
quelle
In der Dokumentation oder in den Antworten auf dieser Seite wird nicht ausdrücklich darauf hingewiesen (obwohl dies von @Naruto impliziert wird), dass
FragmentPagerAdapter
die Fragmente nicht aktualisiert werden, wenn sich die Daten im Fragment ändern, da das Fragment im Speicher bleibt.Selbst wenn Sie nur eine begrenzte Anzahl von Fragmenten anzeigen möchten, müssen Sie FragmentStatePagerAdapter verwenden, wenn Sie Ihre Fragmente aktualisieren möchten (z. B. wenn Sie die Abfrage erneut ausführen, um die listView im Fragment zu aktualisieren).
Mein ganzer Punkt hier ist, dass die Anzahl der Fragmente und ob sie ähnlich sind oder nicht, nicht immer der Schlüsselaspekt ist, der berücksichtigt werden muss. Ob Ihre Fragmente dynamisch sind oder nicht, ist ebenfalls entscheidend.
quelle
FragmentPagerAdapter
in meiner Aktivität einen ViewPager, um zwei Fragmente anzuzeigen - wobei jedes Fragment eine Liste enthält. Meine erste Liste heißt "Alle Berichte" und die zweite Liste ist "Lieblingsberichte". Wenn ich in der ersten Liste auf das Sternsymbol für einen Bericht tippe, wird die Datenbank aktualisiert, um den Favoritenstatus dieses Berichts umzuschalten. Ich wische dann über und sehe diesen Bericht erfolgreich in der Benutzeroberfläche der zweiten Liste. Vielleicht werden die Instanzen im Speicher behalten, aber in einigen Fällen (z. B. in meinen) wird der Inhalt für FragmentPagerAdapterFragmentPagerAdapter
speichert die vorherigen Daten, die vom Adapter abgerufen werden, währendFragmentStatePagerAdapter
der neue Wert bei jeder Ausführung vom Adapter übernommen wird.quelle
FragmentStatePagerAdapter = Zum Aufnehmen einer großen Anzahl von Fragmenten in ViewPager. Da dieser Adapter das Fragment zerstört, wenn es für den Benutzer nicht sichtbar ist und nur savedInstanceState des Fragments zur weiteren Verwendung aufbewahrt wird. Auf diese Weise wird eine geringe Speichermenge verwendet und bei dynamischen Fragmenten eine bessere Leistung erzielt.
quelle
FragmentPagerAdapter : Das Fragment jeder Seite, die der Benutzer besucht, wird im Speicher gespeichert, obwohl die Ansicht zerstört wird. Wenn die Seite wieder sichtbar ist, wird die Ansicht neu erstellt, die Fragmentinstanz jedoch nicht neu. Dies kann dazu führen, dass eine erhebliche Menge an Speicher verwendet wird. FragmentPagerAdapter sollte verwendet werden, wenn das gesamte Fragment im Speicher gespeichert werden muss. FragmentPagerAdapter ruft bei der Transaktion "trennen" (Fragment) auf, anstatt "entfernen" (Fragment).
FragmentStatePagerAdapter : Die Fragmentinstanz wird zerstört, wenn sie für den Benutzer nicht sichtbar ist, mit Ausnahme des gespeicherten Status des Fragments. Dies führt dazu, dass nur wenig Speicher benötigt wird, und kann für die Verarbeitung größerer Datenmengen hilfreich sein. Sollte verwendet werden, wenn dynamische Fragmente wie Fragmente mit Widgets verwendet werden müssen, da deren Daten im savedInstanceState gespeichert werden könnten. Dies wirkt sich auch dann nicht auf die Leistung aus, wenn eine große Anzahl von Fragmenten vorhanden ist.
quelle