Android Tablayout fragment mehrfacher Aufruf mit leeren Werten

  • Hi zusammen,


    ich habe eine MainActivity mit einem RecyclerView, welcher Daten aus einer SQLite-Datenbank anzeigt. Beim Klick auf einen Datensatz soll sich eine DetailActivity öffnen, und weitere Details zu dem jeweiligen Datensatz anzeigen.
    Ich habe auf der DetailActivity ein TabLayout, da die Detaildaten auf 3 Tabs angezeigt werden sollen. Für jeden Tab existiert ein Fragment.
    Wenn ich nun aber einen Datensatz in der MainActivity anklicke, öffnet sich zwar das fragment, aber ohne Daten. Im Logfile sieht man, dass der OnCreateView des fragments insgesamt 3x aufgerufen wird. Beim ersten mal ohne Werte, beim 2. Mal werden die Werte übergeben, beim 3. Mal dann wieder leer.
    Kann mir jemand sagen, warum das fragment 3x aufgerufen wird, und wie ich das beheben kann?
    Danke euch!



    Meine MainActivity:


    NotenDetailsActivity:



    Tab1Fragment:



    Und das Logfile, in dem man erkennt, dass das fragment 3x aufgerufen wird:


  • Hallo


    Wie ich gesehen habe warst du wieder Online. Deshalb nun auch eine Antwort von mir. Leider ist es oft so man gibt sich mühe eine Antwort zu schreiben und der TE schaut nicht mal nach, geht gar nicht online.




    Das Ganze ist eine Eigenart des ViewPager den du verwendest.


    Mit Hilfe des ViewPager ist es ja möglich auch zwischen den Taps zu Swipen.


    Damit das möglich ist werden immer die Nachbar Fragmente schon in den Speicher vorgeladen.


    Du schreibst du hast drei Fragmente, hast du denn auch drei Klassen? Ich denke du hast nur die eine „Tab1Fragment“ oder hast du in den anderen Klassen das gleiche Log?


    Da immer das Nachbar Fragment schon vorgeladen wird, die onCreateView auch drei mal gestartet.


    Eigentlich hat man drei Klassen. Dazu musst du aber auch den Adapter etwas bearbeiten und bestimmt auch dein Layout. Dann würde von jeder Kasse die onCreateView aufgerufen werden wenn ein Swipe erflogt. Beim ersten Start natürlich alle drei. Dann immer die Nachbarn. Die eigene onCrateView von dem Fragment was angezeigt wird zum Zeitpunkt des sichtbar Werdens nicht mehr aufgerufen.


    Mit dem View Pager wirst du immer das Problem haben.


    Damit deine Parameter also das „putin“ auch in den anderen Fragment schon beim voraus laden verfügbar ist wirst du wohl den Adapter etwas bearbeiten müssen.


    Sehr interessant währe wie dein Adapter „PageAdapter“ aussieht.


    Wo und wie hast du den die Tabs definiert Im Layout oder?


    Aufgrund dierser drei zeilen würde ich auf im Layout tippen.




    Was soll das eigentlich die Variablen die werden im Code gar nicht benutzt?


    TabItem tabChats = findViewById(R.id.tabPage1);
    TabItem tabStatus = findViewById(R.id.tabPage2);
    TabItem tabCalls = findViewById(R.id.tabPage3);

  • Hi,


    danke für diene Antwort. Natürlich habe ich täglich reingeschaut, das Problem besteht ja immer noch. Anscheinend war ich nur nicht angemeldet.


    Bevor ich nun versuche, meinen Code irgendwie halbvernünftig zu bearbeiten: Wie müsste das ganze denn vernünftig aussehen?
    Ziel soll es eben sein, eine Liste (mit Datensätzen aus einer Datenbank) anzuzeigen, beim Klick darauf sollen die Detaildaten zum DS angezeigt werden (auf 3 Tabs verteilt).
    Ein Swipen zwischen den Tabs wäre dann schon gut.
    Ich muss dazu sagen, dass ich völliger Java-Neuling bin (bisher nur VB / C#).
    Ich habe im Netz verschiedene Tuts gefunden, allerdings nur entweder "Liste mit Klick auf Detailanzeige (sep. Avtivity), oder die allgemeine Verwendung von Tabs. Ich bekomm es aber nicht hin, beides zu verknüpfen.


    Danke & Grüße

  • Hallo dann zeige doch mal etwas mehr von deinen Code.



    Was bekommst du alles von der DB?
    Du willst also die Daten die von der DB Kommen auf drei Tabs Fragmente aufteilen.
    Wie ist das ? Ändern sich die Daten von der DB wenn du von einen Fragment (Tab) zum anderen Swipst?
    Wenn nicht macht es eigentlich ja auch nichts das die onCreateView vom neuen Fragment beim sichtbar werden nicht aufgerufen wird. Da sie ja schon vorgeladen ist.



    Du könnstet die Daten für die einzelnen Fragmente in verschiedenen Listen oder Cursors Speichen und an die Fragmente Übergeben.



    Wie ich schon sagte wie sieht dein Adapter aus?
    Wie und wo holst du die Detaildaten zum DS?
    Wie Wo Übergiebst du die Daten an die Fargmente?


    Was hast du eine Fragment Klasse in der du verschiedene Daten einblenden willst oder hast du drei Fragmentkassen?


    Ich würde drei mit verschiedenen Layouts machen.



    Wenn sich die Daten beim Swipen von einen Tab zum anderen ändern musst du etwas mehr Aufwand machen denn die onCreateView wird ja beim sichtbar werden nicht durchlaufen.

  • Hi,


    hier der gesamte Code:



    NotenDatabase:


    NotenDao:


    NotenRepository:


    NotesRecyclerAdapter:


    PageAdapter:


    Class Note:

  • MainActivity: Liste aller Datensätze; Beim Klick auf einen Datensatz wird die NotenDetailsActivity aufgerufen.


    NotenDetailsActivity: (enthält das Tablayout mit 4 Tabs).


    Tab1Fragment: (Tab2-4 sind genauso aufgebaut, enthalten nur unterschiedliche Datenfelder)


    Tab2Fragment:

  • Hier noch die Layouts:


    MainLayout (Liste der Datensätze):


    NotenListActivity (für die Anzeige im RecyclerViev):


    DetailsLayout mit Tablayout:


    fragment_tab1.xml:


    fragment_tab2.xml:

  • Hallo ein grundlegender fehler ist in der NotenDetailsActivity. Und zwar in der onCreate.
    Estens brauchst du da keine fragment Transaktion machen ist hier falsch. Das macht dein Viewpager für dich. Auch das übergeben der Argumente in der Activity onCreate ist falsch.
    In deinem Adapter erstelltes du die instanzen der Fragmente mit new. In der activity erstellst du für das erste fragment auch wieder ein neues Objekt mit New. Das ist nicht die gleiche Instanz.


    In der oncreate solltest du die argumente nicht übergeben. Und wenn ja dann sorge dafür das es auch die richtige Instanz ist. Das gleiche Objekt was dein Adapter erstellt.


    Parameter Übergabe würde ich im Adapter machen, habe ich auch schon mal gesagt.


    Somit ist es klar das du keine Argumente in den fragment die der viewpager erstellt hast. Und nichts angezeigt wird.


    Also baue dein Adapter um und übergebe da die Argumente.


    Oder benutze viewmodel.


    Wenn du dir msl eine neue app mit tabs vom Studio erstellen läßt siest du das Prinzip. Auch das da kein Transaktion on der activity notwendig ist.

  • Hi jogimuc,


    erstmal vielen Dank, dass du dir die Zeit nimmst, meinen gesamten Code zu sichten und mir weiterzuhelfen. Ist nicht selbstverständlich.
    Danke für die Hinweise, ich werde morgen versuchen, das entsprechend deinen HInweisen umzubauen. Ich halte dich auf dem Laufenden.
    Hab dir noch ne PN geschickt.

  • Wie übergebe ich die Argumente denn im Adapter? Ich bekomme in der MainActivity ja die Datensatz-ID beim Klick auf den Datensatz. Bisher gebe ich sie mittels Intent an die NotenDetailsActivity. Wie kann ich die jetzt an den Adapter übergeben, bzw. dann an die fragments weitergeben?

  • Der Intent kommt doch in der NotenDetailsActivity an. Dort hast du ja auch versucht die Daten an das Fragment zu übergeben. Nur eben an die das falsche Instanz.


    Erste Möglichkeit beim Aufruf des Adapters übergibst du auch noch die Daten. Die Anzahl der Tabs und den Fragmentmanager übergibst du ja schon.


    Warum nicht auch die Daten. Aber bitte alle für alle Fragmente und nicht nur für das erste.


    Zweite Variante erstelle in der Adapter Klasse eine Methode dafür bei der du die Daten übergibst, warscheilich brauchst du auch den context der activity im Adapter um auf die Daten der db zuzugreifen.


    Um in der Activity auf die Methode aufzurufen. Benutzt du die Instanz des Adapters denn du in der Activity ja erstellt hast.


    Das ist eigentlich einfache OOP.


    Im Adapter übergibst du jedem Fragment seine Argumente, Daten.
    Die du dann in der Fragment Klasse anzeigen läst.


    Denke aber daran was ich am Anfang gesagt habe das immer die Nachbar Fragmente schon vorgeladen werden also es wird nicht beim anzeigen geupdatet.
    Wenn ich mir aber deinen Code ansehe ist das bei deinem Code nicht der Fall.
    Die Daten werden ja nicht in den Tabs verändert sondern nur angezeigt.
    Richtig?
    Somit kannst du Daten auch im Adapter nach dem Objekt erstellen jedem Fragment im bundle übergeben. Wie ich sagte für jedes Fragment nicht nur für das erste.




    Ich kann dir keinen Code geben da ich diese Woche nur am Handy bin.

Jetzt mitmachen!

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