Ich frage mich, ob dies tatsächlich ein Fehler in der Android-API ist:
Ich habe ein Setup wie folgt:
┌----┬---------┐
| | |
| 1 | 2 |
| |┌-------┐|
| || ||
| || 3 ||
└----┴┴-------┴┘
- Ist ein Menü, das Fragment Nr. 2 (Ein Suchbildschirm) im rechten Bereich lädt.
- Ist ein Suchbildschirm, der Fragment Nr. 3 enthält, bei dem es sich um eine Ergebnisliste handelt.
- Die Ergebnisliste wird an mehreren Stellen verwendet (auch als eigenständiges funktionierendes Fragment auf hoher Ebene).
Diese Funktionalität funktioniert perfekt auf einem Telefon (wobei 1 & 2 und 3 ActivityFragment
s sind).
Als ich diesen Code verwendete:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment frag = new FragmentNumber2();
if(toLoad != null) frag.setArguments(toLoad);
transaction.replace(R.id.rightPane, frag);
transaction.commit();
Wo R.id.leftPane
und R.id.rightPane
sind <fragment>
s in einem horizontalen linearen Layout.
Nach meinem Verständnis entfernt der obige Code das residente Fragment und ersetzt es dann durch ein neues Fragment. Genial ... Offensichtlich passiert das nicht, denn wenn dieser Code das zweite Mal ausgeführt wird, tritt die folgende Ausnahme auf:
07-27 15:22:55.940: ERROR/AndroidRuntime(8105): Caused by: java.lang.IllegalArgumentException: Binary XML file line #57: Duplicate id 0x7f080024, tag null, or parent id 0x0 with another fragment for FragmentNumber3
Dies liegt daran, dass der Container für FragmentNumber3 dupliziert wurde und keine eindeutige ID mehr hat. Das ursprüngliche Fragment wurde nicht zerstört (?), Bevor das neue hinzugefügt wurde (meiner Meinung nach bedeutet dies, dass es nicht ersetzt wurde ).
Kann mir jemand sagen, ob dies möglich ist ( diese Antwort deutet darauf hin, dass dies nicht der Fall ist) oder ob es sich um einen Fehler handelt?
Antworten:
Verschachtelte Fragmente werden derzeit nicht unterstützt. Der Versuch, ein Fragment in die Benutzeroberfläche eines anderen Fragments einzufügen, führt zu undefiniertem und wahrscheinlich fehlerhaftem Verhalten.
HINWEIS (gemäß diesem Dokument ): " Hinweis: Sie können ein Layout nicht in ein Fragment aufblasen, wenn dieses Layout a enthält
<fragment>
. Verschachtelte Fragmente werden nur unterstützt, wenn sie einem Fragment dynamisch hinzugefügt werden. "quelle
Fragment
s sind jetzt Teil der Android-API, yay! developer.android.com/about/versions/… .Die Android Support Library unterstützt jetzt auch verschachtelte Fragmente , sodass Sie verschachtelte Fragmentdesigns unter Android 1.6 und höher implementieren können.
Um ein Fragment zu verschachteln, rufen Sie einfach getChildFragmentManager () für das Fragment auf, in dem Sie ein Fragment hinzufügen möchten. Dies gibt einen FragmentManager zurück, den Sie wie gewohnt aus der Aktivität der obersten Ebene verwenden können, um Fragmenttransaktionen zu erstellen. Hier ist beispielsweise ein Code, der ein Fragment aus einer vorhandenen Fragmentklasse hinzufügt:
Um mehr über verschachtelte Fragmente zu erfahren, lesen Sie bitte diese Tutorials
Teil 1
Teil 2
Teil 3
und hier ist ein SO-Beitrag, in dem Best Practices für verschachtelte Fragmente erörtert werden .
quelle
.. Sie können Ihr verschachteltes Fragment in der
destroyview
Methode des übergeordneten Fragments bereinigen :quelle
Ich habe eine Anwendung, die ich entwickle und die ähnlich wie Tabs in der Aktionsleiste aufgebaut ist, die Fragmente startet. Einige dieser Fragmente enthalten mehrere eingebettete Fragmente.
Ich habe den gleichen Fehler erhalten, als ich versucht habe, die Anwendung auszuführen. Es scheint, als würde der Inflator-Fehler angezeigt, wenn Sie die Fragmente innerhalb des XML-Layouts instanziieren, nachdem eine Registerkarte nicht ausgewählt und dann erneut ausgewählt wurde.
Ich habe dieses Problem gelöst, indem ich alle Fragmente in XML durch Linearlayouts ersetzt und dann einen Fragmentmanager / eine Fragmenttransaktion verwendet habe, um die Fragmente zu instanziieren. Im Moment scheint alles korrekt zu funktionieren, zumindest auf Testebene.
Ich hoffe das hilft dir weiter.
quelle
Ich hatte mit dem gleichen Problem zu kämpfen, hatte ein paar Tage damit zu kämpfen und sollte sagen, dass der einfachste Weg, dies zu überwinden, die Verwendung von fragment.hide () / fragment.show () ist, wenn die Registerkarte ausgewählt / nicht ausgewählt ist ().
Wenn eine Bildschirmrotation auftritt, werden alle übergeordneten und untergeordneten Fragmente korrekt zerstört.
Dieser Ansatz hat auch einen zusätzlichen Vorteil: Die Verwendung von hide () / show () führt nicht dazu, dass Fragmentansichten ihren Status verlieren, sodass beispielsweise die vorherige Bildlaufposition für ScrollViews nicht wiederhergestellt werden muss.
Das Problem ist, dass ich nicht weiß, ob es richtig ist, Fragmente nicht zu trennen, wenn sie nicht sichtbar sind. Ich denke, das offizielle Beispiel von TabListener wurde mit dem Gedanken entworfen, dass Fragmente wiederverwendbar sind und Sie den Speicher nicht mit ihnen verschmutzen sollten. Ich denke jedoch, wenn Sie nur wenige Registerkarten haben und wissen, dass Benutzer häufig zwischen ihnen wechseln werden wird angemessen sein, um sie an die aktuelle Aktivität gebunden zu halten.
Ich würde gerne Kommentare von erfahreneren Entwicklern hören.
quelle
Wenn Sie feststellen, dass Ihr verschachteltes Fragment nicht entfernt oder dupliziert wird (z. B. beim Neustart der Aktivität, beim Drehen des Bildschirms), versuchen Sie Folgendes zu ändern:
zu
Wenn oben nicht hilft, versuchen Sie:
gelernt hier
quelle