Listview in ListFragment speichern vor Transaction und wieder herstellen nach Nutzung des Back Buttons

  • Hallo!


    Ich habe da ein Problem mit den Fragmenten. Folgende Situation:


    Ich habe ein ListFragment in welchem in einer Liste eine Navigationsstruktur abgebildet werden soll. Konkret soll man beim Klick auf ein Item in der Liste in die nächste Stufe, also eine Hierarchie-Ebene weiter kommen. Die Listview habe ich über einen Adapter befüllt, den ich an das Fragment gebunden habe. Wird auch sauber dargstellt. Auch das Auswählen eines Items und die Anzeige der nächsten Navigations-Ebende klappt super. Das habe ich über die Fragment Transaction gelöst: Erst das bestehende ListFragment mit remove() entfernt und dann das gleiche Fragment neu erzeugt und mit add() wieder eingefügt. Für eine Rückwärts-Navigation rufe ich auch noch ein addToBackStack auf, bevor ich die Transaktion comitte. Dann die ArrayListe, die den ArrayAdapter befüllt, aktualisiert und an das neue Fragment angebunden. Diese Vorwärts-Navigation klappt super.


    Probleme habe ich aber mit der Rückwärts-Navigation. Der Nutzer soll wenn er den Back Butteon drückt wieder eine Navigations-Ebene zurück springen können. Deswegen habe ich ja auch das addToBackStack in meine Transaktion mit eingebaut. Wenn man nun den Back Button drückt, springt das Fragment auch um (zurück). Allerdings wird die vorherige Listenansicht nicht geladen bzw. wieder aufgebaut.


    Ich gehe mal davon aus, dass ich die Elemente der Liste irgendwo zwischenspeichern müsste, um sie dann beim Aufruf des vorherigen ListFragments für den Wiederaufbau der Liste verwenden zu können. Aber wie soll ich das machen? Ich habe gedacht, dass onSaveInstanceState dabei hilfreich wäre. Diese Methode wird bei der Transaktion aber gar nicht erst aufgerufen (habe ich mit einem Log.d("...","...") überprüft; wird nicht aufgerufen). Was ich dabei heraus gefunden habe, ist, dass onSaveInstanceState bei einer Rotation des Geräts aufgerufen wird. Also von z.B. Portrait auf Landscape oder umgekehrt. Aber das nutzt mir bei meinem Problem nichts.


    Also wie mache ich das am besten, damit meine ListView hinterher wieder hergestellt werden kann? Wo im Code speichere ich die Daten weg? Und vor allem - wo speicher ich die Daten hin? SharedPreferences wäre eine Möglichkeit, wenn ich nur eine weitere Navigations-Ebene hätte. Ich habe aber mehrere Stufen (bis in eine 5. Ebene). Da sind die SharedPreferences keine Lösung mehr, da es ein großer Aufwand wäre zu verfolgen, wo ich mich gerade befinde und welche gespeicherten Informationen für die Liste ich bei einem Schritt rückwärts wieder laden müsste.


    Ich habe mir schon überlegt, dass die Verwendung eines Stacks hiflreich wäre. Erst alle Items auf den Stack schieben. Als letztes Element die Anzahl der Einträge drauf schieben und dann das nächste ListFragment laden. Geht man noch eine Schritt weiter, wieder die aktuellen Element drauf schieben. Geht man einen Schritt zurück, dann zieht man sich die Items der vorherigen Ansicht vom Stack und baut die Liste so wieder auf. Allerdings wollte ich mal fragen, ob es da vielleicht eine elegantere Lösung gibt?


    Die Items in der Liste sind übrigens alles Strings. Pro Eintrag ein String, dargestellt über eine "android.R.layout.simple_list_item_1"-Liste.


    Gruß

  • Wo baust du deinen View im Fragment auf?


    Ich nutzte dafür die onCreateView() - die wird öfter mal aufgerufen als die onCreate().


    Ansonsten probiere doch mal folgendes:


    Neues Android Application Projekt anlegen (minApi 11) und MasterDetailFlow als Basis-Klassenstruktur auswählen - da hast du dann erst mal alles für eine ListActivity mit Fragments.


    Dort sind nur wenige Abhängigkeiten für API 11 drin, einfach die minApi runtersetzen und gucken, wo was schiefgeht.


    Speziell das Laden des ListFragment ist da ein Problem (activity_item_layout.xml), aber da willst du bestimmt ein eigenes Fragment einsetzen.


    Die support lib ist netterweise schon drin...

  • Hallo,


    ich habe das Problem inzwischen gelöst.


    Für die einzelnen Navigations-Inhalte der Listview habe ich eine Klasse "Naviliste" definiert, in welcher alle Items gespeichert sind. Klickt jemand ein item an, dann wird für die neue Listview eine neue Liste generiert. Diese Listen werden indiziert, bekommen also eine feste ID zugewiesen.


    Wenn ich jetzt ein Item in der Listview anklicke, schiebe ich die ID der aktuellen Naviliste auf einen Stack und baue in einem neuen Fragment die neue Liste auf. Geht der User noch einen Schritt weiter, dann das gleiche usw.


    Wenn der Nutzer nun mit dem Back-Button einen Schritt zurück gehen möchte, geht das folgendermaßen:


    Den Aufruf des Back-Button fange ich mit onPressedBack() in der Parent-Activity ab und rufe darüber eine eigene Methode auf. Diese holt sich die zuletzt auf den Stack geschobene ID und baut damit dann in einem neuen Fragment die vorherige Liste wieder auf.


    Gleichzeitig lasse ich einen Zähler mitlaufen, der mitzählt, in welcher Navigationstiefe ich bin. Wird also bei jedem Vorwärts-Navigationsschritt um 1 erhöht. Bei rückwärts eben um 1 reduziert. Damit kann ich dann abfragen, ob der Nutzer irgendwann mal über die Wurzel der Navigation hinaus einen Rückschritt auswählt und in diesem Fall die aktuelle Activity mit ihren Fragmenten über finish() beenden.


    Das funktioniert super. Hat zwar ein wenig gedauert, bis aus der Idee dann der Code geworden ist. Aber es lübbt nu! :)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!