Android Lifecycle-management der Bruchstücke in einem ViewPager und FragmentPagerAdapter
Ich kämpfen, um herauszufinden, was das richtige management von Fragmenten innerhalb einer FragmentActivity
mit einem ViewPager
ist. Bevor ich in die details gehen, eine kurze Zusammenfassung des Problems, das ich bin vor ist die folgende:
Ich habe eine FragmentActivity
mit einem ViewPager
. Die ViewPager
verwendet eine benutzerdefinierte, doch sehr einfachen FragmentPagerAdapter
. Jeder Fragment
innerhalb der ViewPager
verfügt über eine ExpandableListView
. Ich habe auch ein action-bar die Schaltfläche "Aktualisieren". Für jetzt wollen wir davon ausgehen, dass die ViewPager
hat nur eine Fragment
. Die Aktivität angelegt wird, und die Fragment
's ExpandableListView
gefüllt ist (so weit so gut). Wenn der Refresh-button geklickt wird, wird die Handhabung der Methode innerhalb der FragmentActivity
iteriert über die Liste der Fragments
zugewiesen sind FragmentPagerAdapter und fordert refresh()
auf jeden Fragment
zum Auffüllen seiner ListView. Allerdings, wenn die Ausrichtung des Geräts ändert (z.B. von hochformat auf Querformat), die Tätigkeit ist neu-und so sind die Fragmente. Klicken auf die Schaltfläche Aktualisieren nun iteriert über die nicht-initialisiert Fragments
.
Ich weiß, dass ich mich ganz vage, vor allem ohne sample-code, aber bitte Geduld mit mir. Ich habe verfolgt das problem und die Methode Aufrufe wie folgt ab dem Beginn der Anwendung/Tätigkeit:
FragmentActivity.onCreate()
FragmentActivity.setContentView()
FragmentActivity.createPagerFragments()
<-- dies erzeugt ein ArrayList-Fragmente und ordnet Sie zu einem neuen FragmentPagerAdapter die wiederum zugeordnet zu den ViewPager.Fragment.onAttach()
Fragment.onCreate()
<-- hier nichts besonderes, nur den Aufruf der super-Methode.Fragment.onCreateView()
<-- hier nichts besonderes, sondern nur aufblasen das layoutFragment.onActivityCreated()
<-- hier nichts.- << Alles gute, Orientierung Veränderungen im hier >>
FragmentActivity.onCreate()
Fragment.onAttach()
Fragment.onCreate()
FragmentActivity.setContentView()
FragmentActivity.createPagerFragments()
Fragment.onCreateView()
Fragment.onActivityCreated()
- << Refresh-button geklickt >>
FragmentActivity.refresh()
<-- iteriert über die neu erstellte Fragmente aus #13 (nicht die von Android!).- << Absturz: NullPointerException für mExpandableListView im Fragment. >>
Also das problem, wie ich es sehe, ist wie folgt:
Wenn Android neu erstellt, die FragmentActivity
und seine Views
nach einem Wechsel der Bildschirm-Orientierung (Anrufe #9-15 oben), es schafft neue Fragment
Objekte mit Ihrem Zustand wiederhergestellt, was die Originale waren. Jedoch diese werden, angezeigt werden, völlig verwaltet durch die FragmentManager
, und nicht durch die FragmentPagerAdapter
. Im Gegensatz dazu, wenn die FragmentPagerAdapter
wird neu erstellt, zusammen mit der Fragments
in der Aktivität onCreate
- Methode (siehe call #13) die Fragments
, die zugewiesen werden, um die adapter haben nie Ihre Fragment.onCreate()
oder Fragment.onCreateView()
aufgerufenen Methoden überhaupt. Also wenn die refresh () - Methode aufgerufen wird (siehe #17) die Methode iteriert über diese Fragments
, die noch nicht initialisiert wurden. Daher, wenn Sie versuchen, sich zum Auffüllen der ExpandableListView
, die Ansicht Instanz-variable ist NULL
. Dies ist zu erwarten, wie die Instanz-variable wird nur zugewiesen, in der Fragment.onCreateView()
Methode, die niemals aufgerufen wird, wird auf diese Fragments
.
Also meine Frage ist: wie macht man richtig machen Weiterverwendung des re-neu (von Android) Fragments
nach der Bildschirm-Orientierung geändert hat, um zu vermeiden, neue zu erstellen, das nicht initialisiert? Ich muss eine gültige Referenz auf, um zu rufen, deren refresh () - Methode, füllt Sie auf-Nachfrage. Idealerweise, sollten Sie auch zugewiesen werden, um die FragmentPagerAdapter
als gut.
Ich hoffe, ich war klar bei der Beschreibung des Problems und der Grund, dass ich keine Beispiel-code ist da das problem (wie man sehen kann) ist nicht aus dem code selbst, sondern von einem eher falsch (seemigly) re-creation der Fragmente eher als re-use. Aber wenn nötig, kann ich Ihnen Beispiel-code, den ich nur durch diese Art wäre übersichtlicher.
Danke!
InformationsquelleAutor vmivanov | 2013-12-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist viel zu Lesen, aber nach der Lektüre nur Einführung und die Frage und Erfahrung mit FragmentStatePagerAdapter, die ähnlich FragmentPagerAdapter ich kann Ihnen sagen, dass:
Nach der rotation der adapter wird AUTOMATISCH anfügen alten Fragmente. So es scheint, dass, obwohl die Tätigkeit die Erstellung von adapter-hergestellt wird, FragmentManager, die global ist und es ist Instanz bewahren Aktivität Erholung wird erkennen, dass neue FragmentStatePagerAdapter ist kombiniert mit dem gleichen ViewPager und bittet für die gleichen Fragmente und einfach Holen Sie Sie aus dem Fragment ist der BackStack.
Du als designer der Fragmente kann bemerken, dass dieses Verhalten weiterhin durch Aufruf des Fragments.onAttach() und Fragment.onDetach(). Wenn onAttach() Auftritt, ist es entweder die Schöpfung von Ihrem Fragment oder wiederzuverwenden es nach der rotation. Sie sollten in der Lage sein zu unterscheiden, dass Fragment wurde gedreht, die mit der Nutzung von callback onRestoreRnstanceState().
Sehen Sie in den Protokollen viele onCreate() und anderen Staaten, Protokolle gleichzeitig, weil FragmentStatePagerAdapter immer holt/erstellt min 3 Fragmente (außer wenn Sie einstellen, dass Sie nur 2 oder 1), so auch nach Bildschirm-rotation-3-Fragmente werden angefügt aus backstack.
Ich hoffe, dass es geholfen hat.
InformationsquelleAutor Malachiasz
Glaube ich, dass diese Frage, über das Wiederauffinden der aktuellen fragment aus einem ViewPager, wird Ihnen helfen. Wie bereits erwähnt, Fragmente verwaltet werden, indem das Fragment(Staat)PagerAdapter und NICHT-Aktivität oder Fragment-Lebenszyklus.
getItem
Methode. Diese Methode wird aufgerufen, nur einmal pro fragment, auch wenn die Aktivität wird neu erstellt.instantiateItem
Methode. Wahrscheinlich, dies ist der Ort, wo Sie brauchen, um zu halten Ihre Fragmente und nennen Ihre refresh-Methoden.InformationsquelleAutor kgiannakakis
Wie über das hinzufügen dieser Tätigkeit Tag in Ihrem manifest:
oder diese für API 13 oder höher
also wird es nicht neu erstellen, Ihre Fragmente, wenn es änderungen orientiert.
InformationsquelleAutor Dark Leonhart