Fix #4934 返回页面时可能卡进空白页面#5305
Conversation
There was a problem hiding this comment.
Pull request overview
修复 JavaFX 页面快速往返切换时,旧动画 onFinished 回调误移除当前页面节点导致的白屏问题(#4934)。
Changes:
- 在过渡动画结束回调中增加保护条件,避免当
previousNode已重新成为currentNode时被移除。
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| newAnimation.setOnFinished(e -> { | ||
| setMouseTransparent(false); | ||
| getChildren().remove(previousNode); | ||
| if (previousNode != currentNode) { | ||
| getChildren().remove(previousNode); | ||
| } |
There was a problem hiding this comment.
onFinished can still run after a newer setContent(...) call has already started (or is about to start) another transition. In that case this callback may (a) call setMouseTransparent(false) too early for the newer transition, and (b) remove a node that a newer transition is currently animating (even if it’s not currentNode). Consider tracking a monotonically increasing transition/id (or storing the currently active Animation) and in onFinished only performing cleanup when this callback corresponds to the latest transition.
#5305 Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
在我和 Glavo 群的一位群友的设备上之前基本随便点击几下就会卡出空白页面,应用这个修复之后测了几分钟都没卡出来
Gemini 3 解释
这是一个非常典型的 JavaFX 动画与状态并发导致的 Race Condition(竞态条件)问题。问题诊断
问题出现在
TransitionPane.java中,特别是在快速连续导航的场景下(例如 A -> B -> A)。currentNode= A)。setContent(B)。currentNode更新为 B。previousNode被捕获为 A。Platform.runLater启动动画 A -> B。setContent(A)。currentNode更新为 A。previousNode被捕获为 B。[B, A](将 A 重新加回场景)。onFinished回调被触发。getChildren().remove(previousNode),此时该闭包中的previousNode是 A。currentNode已经是 A 了,但旧的动画回调强制移除了 A。TransitionPane为空,屏幕白屏。修复方案
在
TransitionPane的动画结束回调 (onFinished) 中,在移除previousNode之前,必须检查它是否意外地变回了当前的currentNode。如果它现在是当前应当显示的节点,就不应该将其移除。