我正在尝试使用 FadeTransition
在 3 个不同的 AnchorPane
之间切换(点击 Button
),下面是我的代码,
public class TestSlide extends Application {
private ObjectBinding<Node> frontNode;
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
AnchorPane pane1 = new AnchorPane(new Button("1"));
AnchorPane pane2 = new AnchorPane(new Button("2"));
AnchorPane pane3 = new AnchorPane(new Button("3"));
root.getChildren().addAll(pane1, pane2, pane3);
handleAnimation(root);
BorderPane border= new BorderPane(root);
HBox bottom = new HBox(10);
Button front1 = new Button("Pane 1");
Button front2 = new Button("Pane 2");
Button front3 = new Button("Pane 3");
front1.setOnAction((ActionEvent event) -> {
pane1.toFront();
});
front2.setOnAction((ActionEvent event) -> {
pane2.toFront();
});
front3.setOnAction((ActionEvent event) -> {
pane3.toFront();
});
bottom.getChildren().addAll(front1, front2, front3);
border.setBottom(bottom);
Scene scene = new Scene(border,400,400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void handleAnimation(StackPane root) {
frontNode = Bindings.valueAt(root.getChildren(),
Bindings.size(root.getChildren()).subtract(1));
frontNode.addListener((obs, oldNode, newNode) -> {
SequentialTransition fadeOutIn = new SequentialTransition();
if (oldNode != null) {
FadeTransition fadeOut = new FadeTransition(Duration.millis(500), oldNode);
fadeOut.setToValue(0);
fadeOutIn.getChildren().add(fadeOut);
}
if (newNode != null) {
FadeTransition fadeIn = new FadeTransition(Duration.millis(500), newNode);
fadeIn.setFromValue(0);
fadeIn.setToValue(1);
fadeOutIn.getChildren().add(fadeIn);
}
fadeOutIn.play();
});
}
public static void main(String[] args) {
launch(args);
}
}
handleAnimation
方法引用自另一个 SO 帖子。
问题是,
启动应用程序后,单击 Pane 1
按钮
。 -> Transition 将首先显示pane2
,然后是pane1
。现在点击 Pane 3
Button
-> Transition 将首先显示pane2
然后是pane3
.现在点击Pane 2
Button
-> Transition会显示pane2
,上面2点提到的问题不会出现再次出现。
为什么在第 1 点和第 2 点显示实际 Pane 之前转换显示 pane2
?是由于不透明度设置吗?
为什么在第 3 点之后问题得到解决?
如何在不显示第三个 Pane 的情况下使过渡工作到 FadeIn
和 FadeOut
各自的 Pane
?
最佳答案
这里的问题是 StackPane
的子级的初始状态是错误的:所有节点的不透明度为 1。当没有动画运行时,您想要的状态具有所有节点,但最后一个节点完全透明(不透明度 = 0)和最后一个完全不透明(不透明度 = 1)。您应该能够通过正确初始化不透明度来解决此问题:
root.getChildren().addAll(pane1, pane2, pane3);
// set opacity for all but the last child to 0
List<Node> children = root.getChildren();
for (int i = children.size()-2; i >= 0; i--) {
children.get(i).setOpacity(0);
}
否则会发生以下情况:
就在 pane1.toFront()
之后。请注意,(SequentialTransition
确保建立动画开始的状态。
最上面的节点是列表中的最后一个子节点,----...
放在可见“层”的旁边。
Pane 1: opacity = 0
Pane 3: opacity = 1 ------------------------------
Pane 2: opacity = 1
现在 SequentialTransition
的前半部分完成后,看起来如下:
Pane 1: opacity = 0
Pane 3: opacity = 0
Pane 2: opacity = 1 ------------------------------
动画完成后:
Pane 1: opacity = 1 ------------------------------
Pane 3: opacity = 0
Pane 2: opacity = 1
使用 pane3.toFront()
产生类似的结果:
Pane 3: opacity = 0
Pane 1: opacity = 1 ------------------------------
Pane 2: opacity = 1
Pane 3: opacity = 0
Pane 1: opacity = 0
Pane 2: opacity = 1 ------------------------------
Pane 3: opacity = 1 ------------------------------
Pane 1: opacity = 0
Pane 2: opacity = 1
关于JavaFX : StackPane Sequential Transition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57471869/