Animation bei Layoutänderungen

8

Der grundlegende FlowPane in JavaFX legt die Elemente in jedem Fenster bei jeder Größenänderung des Fensters fest. Es gibt jedoch keine Animation und das Ergebnis ist ziemlich verwirrend.

Ich habe einen Change-Listener für die layoutX- und layoutY-Eigenschaften jedes Node innerhalb des FlowPane angeschlossen, und das Ergebnis funktioniert mehr oder weniger, aber manchmal, wenn ich das Fenster schnell skaliere, bleiben die Elemente an inkonsistenten Stellen.

Was vermisse ich?

%Vor%

Ein Gist ist hier für die Lesbarkeit verfügbar und kommt mit einem Testfall: Ссылка

    
Chui Tey 30.05.2013, 04:58
quelle

1 Antwort

10

Das ist eine wirklich nette Idee. Ich mag das. Sie sollten in Erwägung ziehen, Ihren neuen Layout-Manager zu jfxtras hinzuzufügen.

Warum Ihre ursprünglich gepostete Lösung nicht funktioniert

Ihr Problem besteht darin, dass Sie versuchen, einen ursprünglichen Wert für die translateX / Y-Werte aufzuzeichnen und Ihren Übersetzungsübergang mit diesem ursprünglichen Wert zu beenden.

Wenn eine TranslateTransition ausgeführt wird, werden die translateX / Y-Werte geändert. Wenn Sie bei Ihrem aktuellen Code den Bildschirm schnell ändern, bevor Ihre Animationen beendet werden, legen Sie die toX / Y-Eigenschaften von TranslateTransition auf die aktuellen translateX / Y-Werte fest. Dies macht den letzten Ruheplatz der Animation zu einem früheren Zwischenpunkt als zu dem gewünschten endgültigen Ruheplatz für den Knoten (der gewünschte Ort ist nur der Punkt, an dem die translateX / Y-Werte für den Knoten 0 sind).

So beheben Sie es

Der Fix ist einfach - toX / Y für die TranslateTransition sollte immer Null sein, so dass die Transition immer den Knoten in die aktuelle Position des Layouts übersetzt, ohne Translated Delta.

Lösungsbeispiel-Codefragment

Hier ist der Kern des überarbeiteten Übergangscodes:

%Vor%

Beispiel einer Lösungsausgabe

Ausgabe des aktualisierten Animators nach dem Hinzufügen ein paar mehr Rechtecke und Größenanpassung der Bildschirm, um neue Layouts zu zwingen ist (mit der Test-Kabelbaum, die Sie auf Gist geliefert):

Beim Debuggen von Animationen und Beheben von zusätzlichen Problemen mit Ihrem Beispielcode

Beim Debuggen von Animationen finde ich es einfacher, wenn Sie Animationen verlangsamen. Um herauszufinden, wie das gepostete Programm repariert werden kann, setze ich TranslateTransition auf eine Sekunde, um dem Auge genügend Zeit zu geben, um zu sehen, was tatsächlich passiert.

Die Verlangsamung der Animation hat mir gezeigt, dass die tatsächlichen Animationen, die von Ihren Zuhörern generiert wurden, erst nach einem Relay des Knotens stattfinden, wenn der Knoten kurzzeitig an der Zielposition erscheint , dann gehe zurück zu seiner ursprünglichen Position, dann animiere langsam zur Zielposition.

Die Lösung für den anfänglichen Positionierungsfehler besteht darin, den Knoten im Listener zurück in die ursprüngliche Position zu bringen, bevor mit dem Abspielen der Animation begonnen wird.

Ihr Code verwendet eine nodesInTransition-Map, um die aktuell übergehenden Knoten zu verfolgen, aber er fügt nie etwas in die Karte ein. Ich habe ihn in nodeXTransitions und nodeYTransitions umbenannt (weil ich separate x- und y-Übergänge anstelle eines einzelnen Übergangs für beide verwende, da die Verwendung separater einfacher schien). Ich setze die Knotenübergänge in die Map, wenn sie erstellt werden, damit ich alte Übergänge stoppen kann, wenn ich neue erstelle. Dies schien nicht unbedingt notwendig zu sein, da alles ohne die Kartenlogik zu funktionieren schien (vielleicht macht JavaFX so etwas implizit innerhalb seines Animationsrahmens), aber es scheint eine sichere Sache zu sein, also habe ich es behalten.

>

Nachdem ich die oben beschriebenen Änderungen vorgenommen hatte, schien alles in Ordnung zu sein.

Mögliche weitere Verbesserungen

Es gibt vielleicht einige Verbesserungen, die für das Timing von Animationen vorgenommen werden könnten. Wenn eine Animation teilweise abgespielt wird und ein Relayout stattfindet, möchten Sie vielleicht nicht eine ganze Animation von Anfang an für das neue Relayout abspielen. Oder vielleicht möchten Sie, dass sich alle animierten Knoten mit einer konstanten, identischen Geschwindigkeit und nicht für eine bestimmte Dauer bewegen. Aber visuell schien das nicht viel zu bedeuten, also würde ich mir darüber keine Sorgen machen.

Testsystem

Ich habe meine Tests auf Java8b91 und OS X 10.8 durchgeführt.

Vollständiger Code für die aktualisierte Lösung

Vollständiger Code des aktualisierten Layout-Animators:

%Vor%

Beim Vornehmen von Änderungen der Layout-Animation unabhängig von den Einstellungen des User TranslateX / Y

Ein Nachteil der Lösung besteht darin, dass, wenn der Benutzer des benutzerdefinierten Layout-Managers translateX / Y-Einstellungen direkt auf die angelegten Knoten angewendet hat, diese Werte verloren gehen, wenn der Layout-Manager den gesamten Inhalt ausgibt ( da das translateX / Y am Ende auf 0 zurückgesetzt wird).

Um das translateX / Y des Benutzers beizubehalten, könnte die Lösung aktualisiert werden, um benutzerdefinierte Übergänge anstelle von Übergängen zu verwenden. Die benutzerdefinierten Übergänge können auf Eigenschaften eines Übersetzers auf die Knoten angewendet werden ' transformieren . Dann wird nur die zusätzliche Transformation auf jedem Knoten von den Innenfunktionen der Layoutanimation beeinflusst - die ursprünglichen translateX / Y-Werte des Benutzers werden nicht beeinflusst.

Ich habe den Kern aus Ihrer Frage abgezweigt, um die oben erwähnte benutzerdefinierte Übergangserweiterung zu implementieren .

Wenn Sie interessiert sind, können Sie den openjfx-Code für Tab-Header, TitledPanes und Akkordeons ansehen und sehen, wie die Skins für diese Steuerelemente die Animation von Layoutänderungen für ihre untergeordneten Knoten handhaben.

    
jewelsea 30.05.2013, 08:23
quelle

Tags und Links