404 Stimmen

Was ist der Unterschied zwischen FragmentPagerAdapter und FragmentStatePagerAdapter?

Was ist der Unterschied zwischen FragmentPagerAdapter und FragmentStatePagerAdapter?

Über FragmentPagerAdapter sagt Googles Leitfaden:

Diese Version des Pagers ist am besten geeignet, wenn es nur eine Handvoll typischerweise statischer Fragmente gibt, die durchgeblättert werden sollen, wie z.B. eine Reihe von Registerkarten. Das Fragment jeder Seite, die der Benutzer besucht, bleibt im Speicher, obwohl ihre Ansichtshierarchie zerstört werden kann, wenn sie nicht sichtbar ist. Dies kann dazu führen, dass eine erhebliche Menge an Speicher verwendet wird, da Fragment-Instanzen eine beliebige Menge an Zustand halten können. Für größere Seitenmengen sollte man FragmentStatePagerAdapter in Betracht ziehen.

Und über FragmentStatePagerAdapter:

Diese Version des Pagers ist nützlicher, wenn es eine große Anzahl von Seiten gibt, die eher wie eine Listenansicht funktionieren. Wenn Seiten für den Benutzer nicht sichtbar sind, kann ihr gesamtes Fragment zerstört werden und nur der gespeicherte Zustand dieses Fragments bleibt erhalten. Dies ermöglicht es dem Pager, im Vergleich zu FragmentPagerAdapter viel weniger Speicher für jede besuchte Seite zu beanspruchen, jedoch potenziell mit mehr Aufwand verbunden, wenn zwischen den Seiten gewechselt wird.

Also habe ich nur 3 Fragmente. Aber alle sind eigenständige Module mit einer großen Datenmenge.

Fragment1 verarbeitet einige Daten (die Benutzer eingeben) und gibt sie über die Aktivität in Fragment2 weiter, welches nur ein einfaches ListFragment ist. Fragment3 ist ebenfalls ein ListFragment.

Also meine Fragen sind: Welchen Adapter sollte ich verwenden? FragmentPagerAdapter oder FragmentStatePagerAdapter?

318voto

Emmanuel Punkte 13053

Wie in der Dokumentation beschrieben, sollten Sie folgendermaßen darüber nachdenken. Wenn Sie eine Anwendung wie einen Buchleser erstellen würden, möchten Sie nicht alle Fragmente auf einmal in den Speicher laden. Sie möchten Fragmente laden und zerstören, während der Benutzer liest. In diesem Fall verwenden Sie FragmentStatePagerAdapter. Wenn Sie nur 3 "Tabs" anzeigen, die nicht viel schwere Daten enthalten (wie Bitmaps), könnte Ihnen FragmentPagerAdapter gut passen. Beachten Sie auch, dass ViewPager standardmäßig 3 Fragmente in den Speicher lädt. Der erste von Ihnen erwähnte Adapter kann die Ansichtshierarchie zerstören und neu laden, wenn nötig, der zweite Adapter speichert nur den Zustand des Fragments und zerstört es vollständig, wenn der Benutzer dann auf diese Seite zurückkehrt, wird der Zustand wiederhergestellt.

143voto

Steve Punkte 9577

FragmentStatePagerAdapter:

  • mit FragmentStatePagerAdapter wird Ihr nicht benötigtes Fragment zerstört. Eine Transaktion wird durchgeführt, um das Fragment vollständig aus dem FragmentManager Ihrer Aktivität zu entfernen.

  • Der Zustand in FragmentStatePagerAdapter rührt daher, dass es den Bundle Ihres Fragments aus savedInstanceState speichert, wenn es zerstört wird. Wenn der Benutzer zurücknavigiert, wird das neue Fragment mithilfe des Zustands des Fragments wiederhergestellt.

FragmentPagerAdapter:

  • Im Vergleich dazu tut FragmentPagerAdapter nichts dergleichen. Wenn das Fragment nicht mehr benötigt wird, ruft FragmentPagerAdapter detach(Fragment) auf der Transaktion auf, anstatt remove(Fragment) zu verwenden.

  • Das zerstört die Ansicht des Fragments, lässt jedoch die Instanz des Fragments im FragmentManager bestehen. Die Fragmente, die im FragmentPagerAdapter erstellt werden, werden also nie zerstört.

71voto

Linh Punkte 49889

Hier ist der Lebenszyklus jedes Fragments in ViewPager, das 4 Fragmente hat und offscreenPageLimit = 1 (Standardwert)

FragmentStatePagerAdapter

Wechsel zu Fragment1 (Aktivität starten)

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Wechsel zu Fragment2

Fragment3: onCreateView
Fragment3: onStart

Wechsel zu Fragment3

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart

Wechsel zu Fragment4

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

FragmentPagerAdapter

Wechsel zu Fragment1 (Aktivität starten)

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Wechsel zu Fragment2

Fragment3: onCreateView
Fragment3: onStart

Wechsel zu Fragment3

Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart

Wechsel zu Fragment4

Fragment2: onStop
Fragment2: onDestroyView

Schlussfolgerung: FragmentStatePagerAdapter ruft onDestroy auf, wenn das Fragment offscreenPageLimit überschreitet, während FragmentPagerAdapter das nicht tut.

Hinweis: Ich denke, dass wir FragmentStatePagerAdapter für einen ViewPager verwenden sollten, der viele Seiten hat, da dies die Leistung verbessern wird.

Beispiel von offscreenPageLimit:

Wenn wir zu Fragment3 gehen, wird Fragment1 (oder Fragment5, falls vorhanden) zerstört, da offscreenPageLimit = 1. Wenn wir offscreenPageLimit > 1 setzen, wird es nicht zerstört.
In diesem Beispiel gibt es keinen Unterschied zwischen der Verwendung von FragmentStatePagerAdapter oder FragmentPagerAdapter, wenn wir den Tab wechseln, da das Fragment nie onDestroyView und onDestroy aufruft.

Github-Demo hier

39voto

JDenais Punkte 2874

Etwas, was in der Dokumentation oder in den Antworten auf dieser Seite nicht explizit gesagt wird (obwohl von @Naruto angedeutet), ist, dass FragmentPagerAdapter die Fragmente nicht aktualisiert, wenn sich die Daten im Fragment ändern, weil es das Fragment im Speicher behält.

Also, selbst wenn Sie eine begrenzte Anzahl von Fragmenten anzeigen möchten, müssen Sie FragmentStatePagerAdapter verwenden, wenn Sie Ihre Fragmente aktualisieren möchten (sagen wir zum Beispiel, Sie führen die Abfrage erneut aus, um die ListView im Fragment zu aktualisieren).

Mein Hauptpunkt hier ist, dass die Anzahl der Fragmente und ob sie ähnlich sind, nicht immer der Hauptaspekt ist, der berücksichtigt werden sollte. Ob Ihre Fragmente dynamisch sind, ist auch entscheidend.

14voto

vinay kumar Punkte 149

FragmentPagerAdapter speichert die vorherigen Daten, die vom Adapter abgerufen wurden, während FragmentStatePagerAdapter jedes Mal den neuen Wert vom Adapter erhält, wenn es ausgeführt wird.

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