Listview 如何在javafx中滑动(translatetransition)列表视图

Listview 如何在javafx中滑动(translatetransition)列表视图,listview,animation,javafx,Listview,Animation,Javafx,我有一个带有自定义fxml视图的列表视图。一切都很好。现在我想像幻灯片放映一样自动显示我的所有项目。我尝试在列表视图中使用translatetransition。它实现了我想要的功能,但问题是当listview包含更多的项目并且需要滚动时,它只转换通常显示为listview而不滚动的1或2个项目这意味着我只能转换listview默认视图区域,但其他隐藏的项目不会显示。 我的translationtransition代码如下: 当然,它不会显示所有项目。没有比屏幕上显示的更多的ListCells(

我有一个带有自定义fxml视图的列表视图。一切都很好。现在我想像幻灯片放映一样自动显示我的所有项目。我尝试在列表视图中使用translatetransition。它实现了我想要的功能,但问题是当listview包含更多的项目并且需要滚动时,它只转换通常显示为listview而不滚动的1或2个项目这意味着我只能转换listview默认视图区域,但其他隐藏的项目不会显示。

我的translationtransition代码如下:


当然,它不会显示所有项目。没有比屏幕上显示的更多的
ListCell
s(+可能有一些离视口足够近)

通常,要仅显示单元格,可以调用
scrollTo
方法。但是,如果您想控制滚动速度,这不是一个选项

您需要调整滚动位置,您可以访问
滚动条
,并使用
时间线
动画更改其值:

@Override
public void start(Stage primaryStage) {
    ListView<Integer> listView = new ListView<>();

    for (int i = 0; i < 100; i++) {
        listView.getItems().add(i);
    }

    Button btn = new Button("start/stop scrolling");

    Scene scene = new Scene(new VBox(listView, btn));

    // make sure skin is created
    listView.applyCss();
    listView.layout();

    // assuming vertical listview here
    ScrollBar scrollBar = (ScrollBar) listView.lookup(".scroll-bar:"+listView.getOrientation().toString().toLowerCase());

    DoubleProperty pos = new SimpleDoubleProperty();
    DoubleBinding scrollValueBinding
            = scrollBar.maxProperty().subtract(scrollBar.minProperty()).multiply(pos).add(scrollBar.minProperty());

    Timeline timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(pos, 0d)),
            new KeyFrame(Duration.seconds(5), new KeyValue(pos, 1d))
    );

    scrollBar.visibleProperty().addListener((observable, wasVisible, isVisible) -> {
        if (!isVisible) {
            // stop when scrollbar disappears
            timeline.pause();
        }
    });
    timeline.statusProperty().addListener((observable, oldStatus, newStatus) -> {
        if (newStatus == Animation.Status.RUNNING) {
            scrollBar.setDisable(true);
            scrollBar.valueProperty().bind(scrollValueBinding);
        } else if (oldStatus == Animation.Status.RUNNING) {
            scrollBar.setDisable(false);
            scrollBar.valueProperty().unbind();
        }
    });

    timeline.setAutoReverse(true);
    timeline.setCycleCount(Animation.INDEFINITE);

    btn.setOnAction(evt -> {
        if (timeline.getStatus() == Animation.Status.RUNNING || !scrollBar.isVisible()) {
            timeline.pause();
        } else {
            // only run if not already running and scrollbar is visible
            Duration total = timeline.getCycleDuration();
            timeline.playFrom(total.multiply((scrollBar.getValue() - scrollBar.getMin()) / (scrollBar.getMax() - scrollBar.getMin())));
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}
@覆盖
公共无效开始(阶段primaryStage){
ListView ListView=新建ListView();
对于(int i=0;i<100;i++){
getItems().add(i);
}
按钮btn=新按钮(“开始/停止滚动”);
场景=新场景(新VBox(listView,btn));
//确保创建了蒙皮
applyCss();
layout();
//假设这里是垂直列表视图
ScrollBar ScrollBar=(ScrollBar)listView.lookup(“.ScrollBar:”+listView.getOrientation().toString().toLowerCase());
DoubleProperty pos=新的SimpleDoubleProperty();
双绑定滚动值绑定
=scrollBar.maxProperty().subtract(scrollBar.minProperty()).multiply(pos).add(scrollBar.minProperty());
时间线=新时间线(
新关键帧(Duration.ZERO,新键值(pos,0d)),
新关键帧(持续时间。秒(5),新关键值(位置,1d))
);
scrollBar.visibleProperty().addListener((可观察、可见、可见)->{
如果(!isVisible){
//当滚动条消失时停止
timeline.pause();
}
});
timeline.statusProperty().addListener((可观察、oldStatus、newStatus)->{
if(newStatus==Animation.Status.RUNNING){
scrollBar.setDisable(true);
scrollBar.valueProperty().bind(scrollValueBinding);
}else if(oldStatus==Animation.Status.RUNNING){
scrollBar.setDisable(false);
scrollBar.valueProperty().unbind();
}
});
timeline.setAutoReverse(真);
timeline.setCycleCount(Animation.unfinite);
btn.设置动作(evt->{
if(timeline.getStatus()==Animation.Status.RUNNING | | |!scrollBar.isVisible()){
timeline.pause();
}否则{
//仅在尚未运行且滚动条可见时运行
持续时间总计=timeline.getCycleDuration();
timeline.playFrom(total.multiply((scrollBar.getValue()-scrollBar.getMin())/(scrollBar.getMax()-scrollBar.getMin());
}
});
初级阶段。场景(场景);
primaryStage.show();
}
DoubleBinding scrollValueBinding=scrollBar.maxProperty().subtract(scrollBar.minProperty()).multiply(pos).add(scrollBar.minProperty());”这一行上有空指针
@Override
public void start(Stage primaryStage) {
    ListView<Integer> listView = new ListView<>();

    for (int i = 0; i < 100; i++) {
        listView.getItems().add(i);
    }

    Button btn = new Button("start/stop scrolling");

    Scene scene = new Scene(new VBox(listView, btn));

    // make sure skin is created
    listView.applyCss();
    listView.layout();

    // assuming vertical listview here
    ScrollBar scrollBar = (ScrollBar) listView.lookup(".scroll-bar:"+listView.getOrientation().toString().toLowerCase());

    DoubleProperty pos = new SimpleDoubleProperty();
    DoubleBinding scrollValueBinding
            = scrollBar.maxProperty().subtract(scrollBar.minProperty()).multiply(pos).add(scrollBar.minProperty());

    Timeline timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(pos, 0d)),
            new KeyFrame(Duration.seconds(5), new KeyValue(pos, 1d))
    );

    scrollBar.visibleProperty().addListener((observable, wasVisible, isVisible) -> {
        if (!isVisible) {
            // stop when scrollbar disappears
            timeline.pause();
        }
    });
    timeline.statusProperty().addListener((observable, oldStatus, newStatus) -> {
        if (newStatus == Animation.Status.RUNNING) {
            scrollBar.setDisable(true);
            scrollBar.valueProperty().bind(scrollValueBinding);
        } else if (oldStatus == Animation.Status.RUNNING) {
            scrollBar.setDisable(false);
            scrollBar.valueProperty().unbind();
        }
    });

    timeline.setAutoReverse(true);
    timeline.setCycleCount(Animation.INDEFINITE);

    btn.setOnAction(evt -> {
        if (timeline.getStatus() == Animation.Status.RUNNING || !scrollBar.isVisible()) {
            timeline.pause();
        } else {
            // only run if not already running and scrollbar is visible
            Duration total = timeline.getCycleDuration();
            timeline.playFrom(total.multiply((scrollBar.getValue() - scrollBar.getMin()) / (scrollBar.getMax() - scrollBar.getMin())));
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}