首页 > 解决方案 > javafx 自定义 ui 组件 FadeTransition 无法正常工作

问题描述

淡入淡出过渡无法正常工作

我创建了新的 javafx ui 组件并添加了 FadeTransition,但不幸的是,淡入淡出过渡不起作用。当我进入 JFXButton 背景颜色改变但淡入淡出过渡不起作用。我该如何解决?

这是我的代码

启动器类

public class Main extends Application {

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    AnimationButton animationButton = new AnimationButton();
    Scene scene = new Scene(animationButton);
    scene.getStylesheets().add(getClass().getResource("btn.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.setTitle("Custom Control");
    primaryStage.setWidth(300);
    primaryStage.setHeight(200);
    primaryStage.show();
}

动画按钮.java

public class AnimationButton extends AnchorPane{

    private Duration fadeDuration = Duration.millis(1000);
    private FadeTransition fadeTransition;

    @FXML
    private JFXButton animationButton;

    public AnimationButton() {
        
              
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("AnimationButton.fxml"));
        fxmlLoader.setRoot(new AnchorPane());
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    
        animationButton.getStyleClass().add("animation-button");
        fadeDuration = new Duration(3000);
        fadeTransition = new FadeTransition(fadeDuration, animationButton);
        fadeTransition.setAutoReverse(true);
        fadeTransition.setFromValue(0);
        fadeTransition.setToValue(1);
        
    }

    @FXML
    public void mouseEntered(MouseEvent event) {
        fadeTransition.setCycleCount(1); // this way autoreverse wouldn't kick
        fadeTransition.playFromStart();
    }

    @FXML
    public void mouseExited(MouseEvent event) {

        fadeTransition.setCycleCount(2); // starting from autoreverse
        fadeTransition.playFrom(fadeDuration);
    }
    ...
}

这是我的 fxml 文件

<?xml version="1.0" encoding="UTF-8"?>

<?import com.jfoenix.controls.JFXButton?>
<?import javafx.scene.layout.*?>
<fx:root type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.112" 
    xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <JFXButton text="Enjoy it!" id="animationButton" onMouseEntered="#mouseEntered" onMouseExited="#mouseExited"/>
    </children>
</fx:root>

标签: javajavafx

解决方案


目前尚不完全清楚您当前的代码不起作用,但我假设以下内容:

  1. 您希望您的按钮在鼠标进入时淡入,在鼠标退出时淡出。
  2. 淡入淡出功能无法按照您想要的方式工作。
    • 尝试与您的设置类似的操作,我注意到如果鼠标在动画完成之前退出,节点不会淡出。

问题

在似乎试图反转动画的情况下,您正在修改cycleCount属性。该属性不会影响播放的方向,而是会影响动画在停止之前播放的周期数:

定义此动画中的周期数。cycleCount可能是无限重复的INDEFINITE动画,否则必须是> 0

无法更改cycleCountrunning 的Animation。如果cycleCount为 running 更改了 的值,则Animation必须停止并重新启动动画以获取新值。

您将设置cycleCount与设置相结合,autoReverse希望true在设置为时反转动画。物业:cycleCount2autoReverse

定义这是否Animation在交替循环中反转方向。如果trueAnimation则将在第一个循环中前进,然后在第二个循环中反转,依此类推。否则,动画将循环,使得每个循环从开始向前进行。无法更改autoReverserunning 的标志Animation。如果autoReverse为 running 更改了 的值,则Animation必须停止并重新启动动画以获取新值。

此设置可能在某种程度上起作用,尤其是在使用playFromStart()andplayFrom(fadeDuration)时,但这不是执行您想要的操作的正确方法。


解决方案

您想要的是rate根据鼠标是否进入或退出来修改属性。物业rate

Animation定义预期播放的方向/速度。

的绝对值rate表示播​​放的速度Animation,而 的符号rate表示方向。的正值rate表示向前播放,负值表示向后播放并0.0停止跑步Animation

速率1.0是正常播放,2.0 is2 time normal,-1.0` 是向后等。

反转rate运行Animation将导致原地反转方向并在已经过去Animation的部分上回放。Animation

这是一个小例子。它使用Button而不是JFXButton因为我不想引入依赖项。此外,它使用该hover属性,但在功能上等同于使用鼠标进入/鼠标退出处理程序。

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        Button button = new Button("Click me!");
        button.setOnAction(event -> {
            event.consume();
            System.out.println("Button clicked!");
        });

        installAnimation(button);

        primaryStage.setScene(new Scene(new StackPane(button), 300.0, 150.0));
        primaryStage.setTitle("Animation Example");
        primaryStage.show();
    }

    private void installAnimation(Button button) {
        FadeTransition transition = new FadeTransition(Duration.millis(250.0), button);
        transition.setFromValue(0.2);
        transition.setToValue(1.0);

        button.hoverProperty().addListener((obs, wasHover, isHover) -> {
            transition.setRate(isHover ? 1.0 : -1.0);
            transition.play();
        });
        button.setOpacity(transition.getFromValue());
    }

}

请注意以下事项:

  • rate设置为鼠标1.0悬停(进入)和鼠标悬停(退出)时。-1.0
  • 旗帜autoReverse仍然存在false
  • cycleCount保持在1
  • 我打电话play(),不playFromStart()playFrom(Duration)。这很重要,因为play

    Animation从当前位置按 指示的方向播放rate。如果Animation正在运行,则没有效果。

    rate > 0(正向播放)时,如果anAnimation已经定位到最后,则第一个循环不播放,认为已经结束。如果 an位于开头,这也适用于后向 ( rate < 0) 循环。Animation但是,如果Animationhas cycleCount > 1,则将照常播放以下循环。

    Animation到达结束时,Animation停止并且播放头保持在结束处。


推荐阅读