Problem beim Aktualisieren einer ListView in einem Fragment

  • Hi Leute,
    ich sitze jetzt schon seit längerer Zeit an einem Problem und hoffe Ihr könnt mir helfen.


    Also.....
    Ich habe eine SQLite Datenbank aus der ich Daten auslese.
    Diese Daten schreibe ich anhand der Kategorie Nummer in eine ListView in das entsprechende Fragment meiner FragmentActivity.
    Ich benutze so einen schicken SwipeAufbau wo ich oben den Namen der aktuellen Seite ausgebe und man links und rechts den Namen der vorrigen bzw nachfolgenden Kategorie sehen kann.


    Wählt man nun ein Thema aus, öffnet sich ein Dialog in dem man auswählt was man nun mit entsprechendem Listen Inhalt tun will.
    Mir gehts es ums Löschen!


    Ich wähle nun den entsprechenden Eintrag aus und lösche Ihn.
    Es funktioniert alles wunderbar, der Eintrag verschwindet aus der Datenbank. ABER die View also die ListView innerhalb meines Fragments aktualisiert sich einfach nicht. JEDENFALLS NICHT SOFORT. Wische ich ZWEI Elemente weiter und wieder zurück ist die Ansicht aktualisiert. So verhält es sich mit jeder Seite der ListView. Lösche ich einen Eintrag auf Seite 5 muss ich nach links auf Seite 3 oder nach rechts auf Seite 7 wischen. Gehe ich anschließend wieder auf das AusgangsFragment zurück ist es aktualisiert.


    Ich schaffe es aber nicht anhand eines Befehls das Fragment bzw die ListView sich aktualisieren zu lassen!


    Kann mir Jemand vielleicht einen Tip geben oder helfen?

  • Meiner Meinung nach lieferst du zu wenig Fakten für eine seriöse Hilfestellung.


    Welche Art Adapter wird verwendet?
    Wie sieht dein Lösch-Code aus?


    ...um nur mal die erstbesten Fragen zu nennen, die sich dem uneingeweihten Leser stellen ;)


    Die "zwei Seiten" Beobachtung wird sich vermutlich mit Caching erklären lassen.

  • Es ist wahrscheinlich nicht so kompliziert. :)
    In der class für das Fragment ( extends ListFragment ) wirst du ja wahrscheinlich über eine SimpleCursorAdapter die Liste anzeigen lassen. Diesen Code am besten in eigenen Routine speichern. Hast du ja vielleicht schon?
    Ich nenne sie dann z.Bsp.

    Code
    public void refreshLayout() {


    Jetzt musst du nur noch nach dem löschen diese Routine aufrufen.


    Ich hoffe es klappt



  • Hi,
    also hier erst einmal mein Adapter:



    Dann meine Methoden um die Daten zu löschen


  • Es ist wahrscheinlich nicht so kompliziert. :)
    In der class für das Fragment ( extends ListFragment ) wirst du ja wahrscheinlich über eine SimpleCursorAdapter die Liste anzeigen lassen. Diesen Code am besten in eigenen Routine speichern. Hast du ja vielleicht schon?
    Ich nenne sie dann z.Bsp.

    Code
    public void refreshLayout() {


    Jetzt musst du nur noch nach dem löschen diese Routine aufrufen.


    Ich hoffe es klappt


    Hi,
    ich habe den Code mit meinem Adapter in einer eigenen Routine: UpdateFragment()
    Ich rufe die Routine nach dem Löschen auf. Mein Problem bleibt aber bestehen, dass die Daten erst aktualisiert in der ListView dargestellt werden, wenn ich zwei mal nach rechts und wieder zurück wische. Alternative geht natürlich auch mit dem Home Button wieder in die vorige Activity zu gehen und die Activity "ZeigListe" neu aufzurufen. Bei einem NeuAufruf der Activity ist natürlich auch alles schick. Auch wenn ich nach meinem Löschen der Daten die
    Activity Liste zerstöre und mit Intent neu aufrufe ist alles ok. Blos das sollte ja nicht der Weg sein -ausserdem siehts scheisse aus wenn sich die Liste so komplett neu aufbaut.


    Ich muss doch dem ListView ganz einfach sagen können, jetzt aktualisiere Dich doch komplett einmal neu. Den Adapter mit den neuen Daten hab ich ja in meiner Methode: updateFragment der ListView schon zugewiesen.

  • Ich würde normalerweise (wie mein Vorredner) einen CursorAdapter für sowas verwenden;
    wenn ich einen Custom-Adapter verwende (wie du in deinem Code), dann verwende ich adapter.notifyDataSetChanged() für den Fall, das sich Daten geändert haben.
    Im Falle des Löschens würde ich dem Adapter eine delete() Funktion spendieren, die das entsprechende Item aus der internen Datenstruktur entfernt und abschließend das notify... ausführt (die Datenbankabfrage erneut auszuführen mag für ein paar Datensätze OK sein, aber was wenn deine Tabelle mal mehrere 1000 Einträge hat?)


    Allerdings sollte deine Methode (neuen Adapter setzen) auf den ersten Blick eigentlich auch funktionieren, da das setAdapter() die Liste eigentlich auch zum Redraw animiert...
    Ist es sicher, das der neue Adapter den überzähligen Datensatz nicht mehr enthält (per Debugger oder Log.d() geprüft)?


    Deine getView() Methode solltest du in jedem Fall noch mal überarbeiten :)
    Der convertVew wird nicht aus Spaß übergeben, sondern damit man ihn wiederverwendet, und für jedes Item erneut einen Font zu laden (immer wieder, dank des ignorierten convertView) ist sicher auch nicht die effizienteste Art, mit den Resourcen umzugehen.



  • Ich würde normalerweise (wie mein Vorredner) einen CursorAdapter für sowas verwenden;
    wenn ich einen Custom-Adapter verwende (wie du in deinem Code), dann verwende ich adapter.notifyDataSetChanged() für den Fall, das sich Daten geändert haben.
    Im Falle des Löschens würde ich dem Adapter eine delete() Funktion spendieren, die das entsprechende Item aus der internen Datenstruktur entfernt und abschließend das notify... ausführt (die Datenbankabfrage erneut auszuführen mag für ein paar Datensätze OK sein, aber was wenn deine Tabelle mal mehrere 1000 Einträge hat?)


    Ich habe eben nochmal versucht mit notify ein ReDraw zu erzwingen, aber auch hier Fehlanzeige! War nämlich auch der Meinung das ein setAdapter das erzwingt und wollte das quasi als harte Lösung erstmal so drinn lassen....Ich glaube ich bau das mal alles auf CursorAdapter um und zerpflücke nochmal alles.


    Allerdings sollte deine Methode (neuen Adapter setzen) auf den ersten Blick eigentlich auch funktionieren, da das setAdapter() die Liste eigentlich auch zum Redraw animiert...
    Ist es sicher, das der neue Adapter den überzähligen Datensatz nicht mehr enthält (per Debugger oder Log.d() geprüft)?


    Habe dazu mal 3 Bilder angefügt. Wie gesagt ich bin der Meinung mit den Daten und dem Adapter ist alles io. Vielleicht sieht ja an meinen
    Screenshots irgendwer hier noch etwas, was ich nicht sehe.


    Bild 1 (debug1.png) zeigt den Inhalt des gesetzten Adapters auf meiner ListView vor dem delete.
    Bild 2 (debug2.png) zeigt den Adapter der auf die ListView gesetzt werden soll.
    Bild 3 (debug3.png) ziegt nun den Inahlt nach dem setzen des neuen Adapters.


    Deine getView() Methode solltest du in jedem Fall noch mal überarbeiten :)
    Der convertVew wird nicht aus Spaß übergeben, sondern damit man ihn wiederverwendet, und für jedes Item erneut einen Font zu laden (immer wieder, dank des ignorierten convertView) ist sicher auch nicht die effizienteste Art, mit den Resourcen umzugehen.


    KEINE FRAGE! Um Gottes Willen. Mir war es auch ein wenig peinlich, meinen Code den ich bisher habe zu posten, da dort viel zusammen kopierter
    Mist ist um überhaupt erst einmal einen Einstieg zu finden. Bin erst seit 2 Wochen auf Apps/Java. Habe Java mal vor 10 Jahren in der Ausbildung
    gehabt und mache eher C#, C++ und Desktop Anwendungen. Finde aber die App Geschichte und gerade Android/Google sehr spannend! Aber da muss ich
    noch sehr viel optimieren.

  • Oh Gott! Nach einem Tag wirklich extremster Kopfschmerzen hab ich es eben gefunden!!!


    list.setAdapter(adapter);


    ich hatte list nicht in meinem SectionFragment als variable definiert sondern direkt in der FragmentActivity und das auch noch statisch.
    Somit hat er wohl nur beim wirklich zerstören der gesamten Activity eine Änderung erkannt. KUNSTSTÜCK!


    Nun geht es erst einmal so wie ich es möchte.

  • Zitat

    Nach einem Tag wirklich extremster Kopfschmerzen hab ich es eben gefunden!!!

    Hehe - und danke für die Aufklärung, so muss sich jetzt keiner mehr nen Kopf machen :)
    Bin ich froh, das die Ursache am geposteten Sourcecode nicht erkennbar war ;)

  • Hehe - und danke für die Aufklärung, so muss sich jetzt keiner mehr nen Kopf machen :)
    Bin ich froh, das die Ursache am geposteten Sourcecode nicht erkennbar war ;)


    Ja das nächste Mal sollte ich glaub ich mal den gesamten Code posten. Danke erstmal an ALLE die sich für mich den Kopf zerbrochen haben und versucht haben mir zu helfen! DANKE

Jetzt mitmachen!

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