Verschachtelte Fragmente verschwinden beim übergang animation
Hier ist das Szenario: Aktivität beinhaltet fragment A
, die wiederum verwendet getChildFragmentManager()
hinzufügen Fragmente A1
und A2
in seiner onCreate
etwa so:
getChildFragmentManager()
.beginTransaction()
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()
So weit, So gut, alles läuft wie erwartet.
Wir dann führen Sie die folgende Transaktion in der Aktivität:
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(anim1, anim2, anim1, anim2)
.replace(R.id.fragmentHolder, new FragmentB())
.addToBackStack(null)
.commit()
Während des übergangs, die enter
Animationen für fragment B
läuft korrekt, aber Fragmente A1 und A2 ganz verschwinden. Wenn wir das zurücksetzen der Transaktion mit der Zurück-Taste, Sie richtig initialisieren und anzeigen, die normalerweise während der popEnter
animation.
In meinem kurzen Test, es wurde seltsamer - wenn ich die Animationen für die Kind-Fragmente (siehe unten), die exit
animation ausgeführt wird, periodisch, wenn wir hinzufügen fragment B
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(enter, exit)
.replace(R.id.fragmentOneHolder, new FragmentA1())
.replace(R.id.fragmentTwoHolder, new FragmentA2())
.commit()
Den Effekt, den ich erzielen will ist einfach, ich möchte die exit
(oder sollte es sein popExit
?) animation auf fragment A
(anim2) zu laufen, zu animieren, das ganze Behältnis, einschließlich seiner verschachtelten Kinder.
Gibt es irgendeine Möglichkeit das zu erreichen?
Bearbeiten: Bitte suchen Sie einen Testfall hier
Edit2: Dank @StevenByle für schob mich, es weiter zu versuchen mit der statischen Animationen. Anscheinend kann man Animationen auf ein pro-op-basis (nicht global für die ganze Transaktion), das heißt, die Kinder haben, können eine unbestimmte statische animation gesetzt, während Ihre Eltern können eine andere animation und die ganze Sache verpflichtet werden können in einer Transaktion. Siehe die Diskussion unten und die aktualisierte test-Fall-Projekt.
R.id.fragmentHolder
mit Bezug auf A, A1, A2, etc?fragmentHolder ist eine id, die in der Aktivität layout, fragment{Eins,Zwei} - Halter in Ein fragment-layout. Alle drei sind Verschieden. Fragment A wurde zunächst Hinzugefügt fragmentHolder (ich. e., fragment B ist das ersetzen von fragment A).
Erstellt habe ich ein Beispiel-Projekt hier: github.com/BurntBrunch/NestedFragmentsAnimationsTest , es gibt auch eine apk enthalten, in das repository. Dies ist eine wirklich lästige Fehler und ich bin auf der Suche nach einem Weg, das zu umgehen (vorausgesetzt, dass es nicht in meinem code).
Ich weiß ein bisschen mehr über dieses Thema. Der Grund, warum die Fragmente verschwinden ist, weil die Kinder, Griff die Lebenszyklus-Ereignisse vor den Eltern. Im wesentlichen, A1 und A2 entfernt werden, bevor Ein und, da Sie nicht über Animationen eingestellt, verschwinden Sie schlagartig. Ein Weg, um etwas abzumildern, ist dies explizit zu entfernen, A1 und A2 in der Transaktion, ersetzt die A., Die Art und Weise, Sie zu animieren, wenn Sie verlassen, aber Ihre animation Geschwindigkeit im Quadrat, da der übergeordnete container ist auch animierend. Eine Lösung, die nicht produzieren, dieses Artefakt würde geschätzt werden.
Die änderung(ersetzen des starter-fragment), die Sie erwähnen, in der Frage ist die richtige, die Sie wollen zu tun, oder ist es nur ein Beispiel? Sie rufen die
changeFragment
Methode nur ein einziges mal?
InformationsquelleAutor Delyan | 2013-02-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Um zu vermeiden, dass die Benutzer sehen die verschachtelten Fragmente, die verschwinden, wenn die parent-fragment entfernt/ersetzt in einer Transaktion könnten Sie "simulieren" diese Fragmente noch vorhanden, indem Sie ein Bild von Ihnen, als Sie auf der Leinwand erschien. Dieses Bild verwendet als hintergrund für die verschachtelten Fragmente, Behälter, so dass selbst wenn der Blick auf die verschachtelten fragment Weg gehen, wird das Bild simulieren Ihre Anwesenheit. Auch sehe ich nicht ein, verlieren die Interaktivität mit den verschachtelten fragment Ansichten, wie ein problem, weil ich nicht glaube, Sie würden wollen, dass der Benutzer auf Sie einwirken, wenn Sie nur in den Prozess der entfernt wird(wahrscheinlich als user-action).
Habe ich eine kleines Beispiel mit dem Aufbau des Hintergrundbildes(etwas basic).
Wow, so schmutzig. Die Längen, die uns Android-Entwickler haben nur für einige Glätte
ich Habe einen Viewpager Aus der Zweiten tab-ich bin das ersetzen von anderen fragment, und wenn ich drücken wieder drauf, die ich brauche, um zu zeigen, viewpager zweite Registerkarte,es ist das öffnen aber es zeigt leere Seite. Ich habe versucht, was Sie vorgeschlagen, in den oben genannten thread, aber trotzdem ist es dasselbe.
Problem bleibt, wenn der Benutzer kommt zurück, wie @Harish schrieb
Meine Antwort ist sehr alt und wurde hacky auch in der Zeit, als es zu schreiben. Überprüfen Sie die anderen Antworten, wie kcoppock ein, um zu sehen, ob Sie das problem lösen.
InformationsquelleAutor Luksprog
So scheint es eine Menge verschiedene Problemumgehungen für diese, basiert aber auf @Jayd16 Antwort, ich denke ich habe eine ziemlich solide catch-all-Lösung, die immer noch erlaubt für die übergangs-Animationen auf der Kind-Fragmente und erfordert nicht tun, einen bitmap-cache des Layouts.
Haben eine
BaseFragment
Klasse, die Sie erweitertFragment
, und machen Sie alle Ihre Fragmente die Klasse erweitern (nicht nur die Kind-Fragmente).In diesem
BaseFragment
- Klasse fügen Sie den folgenden:Tut es, leider, erfordern Reflexion; da diese Problemumgehung ist für die Unterstützung der Bibliothek, Sie laufen nicht das Risiko der zugrunde liegenden Implementierung ändern, es sei denn, Sie aktualisieren Sie Ihre support-Bibliothek. Wenn Sie die support-library von der Quelle, könnte man hinzufügen, ein accessor für die nächste animation resource ID
Fragment.java
und entfernen Sie die Notwendigkeit für Reflexion.Diese Lösung beseitigt die Notwendigkeit, zu "erraten" der Eltern, die animation Dauer (so dass das "nichts tun" - animation haben die gleiche Dauer wie die der Eltern beenden-animation), und können Sie noch tun, benutzerdefinierte Animationen auf der Kind-Fragmente (z.B. wenn Sie swapping-Kind-Fragmente, um mit verschiedenen Animationen).
Genial!!! Ich danke Ihnen sehr. Einfach, schnell, einfach und effektiv
Sie müssen die nextAnim aus der Eltern fragment-nicht das aus dem Kind. Das ist der springende Punkt.
Vielen Dank für diese sehr nützliche Lösung, aber es erfordert ein kleines update, um die Arbeit mit der aktuellen support library (27.0.2, weiß nicht, welche version brach diese code).
mNextAnim
ist jetzt innerhalb einermAnimationInfo
Objekt. Sie können Zugang es so :Field animInfoField = Fragment.class.getDeclaredField("mAnimationInfo");
animInfoField.setAccessible(true);
Object animationInfo = animInfoField.get(fragment);
Field nextAnimField = animationInfo.getClass().getDeclaredField("mNextAnim");
möchte weitere eine weitere Zeile hinzufügen von code nach deiner.
val nextAnimResource = nextAnimField.getInt(animationInfo);
zu ersetzen Sie die Zeileint nextAnimResource = nextAnimField.getInt(fragment);
InformationsquelleAutor kcoppock
War ich in der Lage zu kommen mit eine ziemlich saubere Lösung. IMO seine Beine hacky, und dies ist zwar technisch das "zeichnen einer bitmap" Lösung zumindest seine abstrahiert, indem das fragment lib.
Stellen Sie sicher, dass Ihr Kind frags überschreiben einer übergeordneten Klasse mit diesem:
Wenn wir einen exit-animation auf das Kind frags, Sie wird animiert werden, anstatt blinken Weg. Wir können dies ausnutzen, indem er eine animation, die einfach sind, zieht der Kind-Fragmente mit voller alpha für eine Dauer. Auf diese Weise, bleiben Sie sichtbar in der Eltern-fragment, wie es animiert wird, geben Sie das gewünschte Verhalten.
Die einzige Frage, die ich denken kann, ist das nachverfolgen der Dauer. Ich könnte vielleicht legen Sie es auf eine große-ish Zahl, aber ich fürchte, das könnte performance-Probleme, wenn seine noch-Zeichnung, animation irgendwo.
Es funktioniert bei mir auch. GG 🙂
Es hilft, danke. Wert der Dauer, Zeit spielt keine Rolle
sauberste Lösung so weit
Schön, vielen Dank!
InformationsquelleAutor Jayd16
Im posting meine Lösung für die Klarheit.
Die Lösung ist ganz einfach. Wenn Sie versuchen, Sie zu imitieren der Eltern fragment Transaktion animation einfach fügen Sie eine benutzerdefinierte animation auf dem Kind-fragment Transaktion mit derselben Dauer. Oh, und stellen Sie sicher, dass Sie die benutzerdefinierte animation vor add().
Xml-R. anim.keiner (Meine Eltern öffnen/schließen-animation Zeit ist 250ms)
Das war toll. Jedoch war ich immer die Verzögerung beim Umschalten mein Kind-Fragmente. um dies zu vermeiden, setzen Sie einfach den 2. parameter mit no anim:
fragmentTransaction.setCustomAnimations(R.anim.none, 0, R.anim.none, R.anim.none)
InformationsquelleAutor Maurycy
Verstehe ich das möglicherweise nicht in der Lage, vollständig zu lösen, dein problem, aber vielleicht wird Anzug jemand anderen Bedürfnisse, die Sie hinzufügen können
enter
/exit
undpopEnter
/popExit
Animationen, um Ihre KinderFragment
s eigentlich nicht bewegen/animierenFragment
s. Solange die Animationen haben die gleiche Dauer/offset-als Eltern -Fragment
Animationen, erscheinen Sie zu bewegen/animieren von den Eltern animation.Vereinbart, dies ist mehr ein workaround als eine Wasserdichte Lösung, und kann als leicht zerbrechlich. Aber es funktioniert für einfache Fälle.
InformationsquelleAutor Steven Byle
können Sie dies tun, in das Kind-fragment.
InformationsquelleAutor peng gao
@@@@@@@@@@@@@@@@@@@@@@@@@@@@
BEARBEITEN:
Ich landete unimplementing diese Lösung, da gab es andere Probleme, die dieser hat. Platz vor kurzem kam mit 2 Bibliotheken, die ersetzen Fragmente. Ich würde sagen, das könnte tatsächlich eine bessere alternative sein als der Versuch, die hack-Fragmente, etwas zu tun die google nicht wollen, dass Sie tun.
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Ich dachte, ich würde setzen Sie diese Lösung, um Menschen helfen, die dieses problem in der Zukunft. Wenn Sie die Ablaufverfolgung über die original-Plakate Gespräch mit anderen Menschen, und betrachten Sie den code, den er geschrieben, sehen Sie die ursprünglichen Verfasser kommt schließlich zu dem Schluss von no-op-animation auf der Kind-Fragmente während der Animation der Eltern-fragment. Diese Lösung ist nicht ideal, da es zwingt Sie, um zu halten verfolgen von alle der Kind-Fragmente, die mühsam sein kann, wenn mit einem ViewPager mit FragmentPagerAdapter.
Seit ich Kind Fragmente, die alle über dem Platz, ich kam mit dieser Lösung, die effizient und modular (so kann es leicht entfernt werden), falls Sie jemals lösen und diese no-op-animation wird nicht mehr benötigt.
Gibt es viele Möglichkeiten, Sie können diese auch umzusetzen. Ich entschied mich für die Verwendung einer singleton -, und ich nenne es ChildFragmentAnimationManager. Es wird grundsätzlich in der Spur zu halten von einem Kind-fragment für mich und seine Mutter-und eine no-op-animation für die Kinder, wenn Sie gefragt.
Als Nächstes müssen Sie eine Klasse, die Sie erweitert-Fragment, das alle Ihre Fragmente verlängern (zumindest Ihr Kind Fragmente). Ich hatte auch schon diese Klasse, und ich nenne es BaseFragment. Wenn eine Fragmente-Ansicht erstellt wurde, fügen wir ihn zu der ChildFragmentAnimationManager, und entfernen Sie Sie, wenn es zerstört wird. Sie könnten dies tun onAttach/Trennen, oder anderen passenden Methoden in der Reihenfolge. Meine Logik für die Auswahl von Erstellen/Zerstören Aussicht war, denn wenn ein Fragment nicht im Blick hat, interessiert mich nicht animieren es weiter zu sehen. Dieser Ansatz sollte auch besser mit ViewPagers, die Fragmente verwenden, so werden Sie nicht halten den überblick über jedes einzelne Fragment, das eine FragmentPagerAdapter hält, sondern nur 3.
Nun, dass alle Ihre Fragmente im Speicher gespeichert werden, die von der übergeordneten fragment, rufen Sie animieren, auf Sie und Ihr Kind Fragmente wird nicht verschwinden.
Auch, nur damit Sie es haben, hier ist die no_anim.xml Datei, die in Ihrem res/anim Ordner:
Wieder, ich glaube nicht, dass diese Lösung perfekt ist, aber es ist viel besser, als für jede Instanz, die Sie haben ein Kind Fragment, das implementieren benutzerdefinierter code in der übergeordneten fragment, um zu verfolgen jedes Kind. Ich bin dort gewesen, und es macht keinen Spaß.
InformationsquelleAutor spierce7
Ich glaube, ich fand eine bessere Lösung für dieses problem als Snapshots des aktuellen fragments in eine bitmap als Luksprog vorgeschlagen.
Der trick ist, verstecken das fragment entfernt oder getrennt wird und erst nach der Animationen abgeschlossen sind, das fragment wird entfernt oder getrennt in seinem eigenen fragment Transaktion.
Vorstellen, dass wir
FragmentA
undFragmentB
sowohl mit sub-Fragmente. Nun, wenn Sie normalerweise tun würde:Statt Sie
Nun für die Implementierung des Fragments:
InformationsquelleAutor Danilo
Ich hatte das gleiche Problem mit map fragment. Es hielt zu verschwinden, während die Ausfahrt animation von der enthaltenden fragment. Die Problemumgehung besteht darin, hinzufügen einer animation für das Kind Kartenausschnitts halten Sie sichtbar, während der Ausgang der animation des übergeordneten fragment. Die animation des Kind-fragments hält seine alpha auf 100% während der Laufzeit.
Animation: res/animator/keep_child_fragment.xml
Die animation wird dann angewendet, wenn die Karte fragment Hinzugefügt wird, um die Eltern-fragment.
Eltern fragment
Schließlich die Dauer des Kind-fragments animation ist in einer resource-Datei.
values/integers.xml
InformationsquelleAutor Evgenii
Animieren dissapearance der neasted Fragmente wir können erzwingen, dass pop wieder Stapel auf ChildFragmentManager. Diese werden ausgelöst, übergang animation. Um dies zu tun, müssen wir aufholen OnBackButtonPressed event oder listen für backstack änderungen.
Hier ist ein Beispiel mit code.
InformationsquelleAutor Mateusz Biedron
Ich habe vor kurzem lief in dieses problem, in meiner Frage: Verschachtelten Fragmente, die den übergang falsch
Habe ich eine Lösung, löst diese, ohne zu speichern ein bitmap, noch mit der spiegelung oder andere unbefriedigende Methoden.
Ein Beispiel-Projekt können hier eingesehen werden: https://github.com/zafrani/NestedFragmentTransitions
Ein GIF von der Wirkung kann hier eingesehen werden: https://imgur.com/94AvrW4
In meinem Beispiel gibt es 6 Kinder, Fragmente, aufgeteilt zwischen zwei Eltern-Fragmente. Ich bin in der Lage zu erreichen, die übergänge für die Einreise, Ausreise -, pop-und push ohne Probleme. Änderungen an der Konfiguration und Rücken sind auch erfolgreich behandelt werden.
Den Großteil der Lösung ist in meinem BaseFragment (das fragment erweitert durch meine Kinder und Eltern-Fragmente) onCreateAnimator Funktion die wie folgt aussieht:
Die Tätigkeit und die Eltern-fragment sind verantwortlich für die Zustände dieser Boolesche Werte. Es ist einfacher zu sehen, wie und wo aus meinem Beispiel-Projekt.
Ich bin nicht mit Unterstützung Fragmente in meinem Beispiel, aber die gleiche Logik kann verwendet werden, mit Ihnen und Ihrer onCreateAnimation Funktion
InformationsquelleAutor zafrani
Einen einfachen Weg, um dieses problem zu beheben ist, verwenden Sie die
Fragment
Klasse aus dieser Bibliothek anstelle der standard-Bibliothek-fragment-Klasse:https://github.com/marksalpeter/contract-fragment
Als seitliche Anmerkung, das Paket enthält auch eine nützliche delegate-Muster genannt
ContractFragment
dass Sie finden könnten, die nützlich für die Entwicklung Ihrer apps-Nutzung der Eltern-Kind-fragment Beziehung.InformationsquelleAutor Mark Salpeter
Aus der obigen Antwort von @kcoppock,
wenn Sie Aktivität->Fragment->Fragmente ( multiple stacking, das folgende hilft ), a-Moll Bearbeiten, um die beste Lösung IMHO.
InformationsquelleAutor alekshandru
Mein problem wurde auf die Eltern-fragment-Entfernung (ft.entfernen(fragment)), Kinder-Animationen wurden nicht geschieht.
Das grundlegende problem ist, dass das Kind Fragmente werden sofort ZERSTÖRT werden, BEVOR die Eltern fragment aufregende animation.
Kind Fragmente benutzerdefinierte Animationen nicht ausgeführt werden, auf die Eltern Fragment Entfernung
Als andere haben, entgangen ist, versteckt der ELTERN (und des Kindes) vor, um ELTERN zu entfernen, ist der Weg zu gehen.
Wenn Sie wirklich wollen, entfernen Sie die Eltern-sollten Sie vielleicht einen listener auf Sie benutzerdefinierte animation, um zu wissen, wenn die animation beendet ist, so können Sie sicher machen einige Abschluss auf der Übergeordneten Fragment (entfernen). Wenn Sie dies nicht tun, in einer zeitgemäßen Weise, könnten Sie am Ende töten die animation. N. B die animation erfolgt auf asynchrone queue von seiner eigenen.
BTW brauchen Sie nicht benutzerdefinierte Animationen auf dem Kind-fragment, denn Sie werden Erben der Eltern-Animationen.
InformationsquelleAutor Ed Manners