如果我创建一个ListView:
new ListView<>(FXCollections.observableArrayList("1", "2", "3"))
Run Code Online (Sandbox Code Playgroud)
我希望它创建一个包含3行的ListView.但事实并非如此.它创建了一个大约17行的ListView.有没有办法告诉ListView始终是高度,以便其中的任何项目始终显示但没有空行?
拥有自动宽度也很有用,因此它总是与最宽的行一样宽.
这样做的一个目的是,它可以在ScrollPane中使用.我知道它有自己的滚动条,但它们没有提供足够的控制.
小智 7
不幸的是,ObservableList没有一个漂亮,干净的大小属性供我们绑定.相反,它可以通过在列表中添加ListChangeListener来实现,至少,这就是我过去的做法.默认情况下,每行的大小应为24px,并且我们需要在ListView的边缘顶部和底部有一个额外的像素.否则我们仍然会显示ListView的滚动条.首先,我们将创建ObservableList和ListView,并设置ListView的初始高度:
/*
* Each row in a ListView should be 24px tall. Also, we have to add an extra
* two px to account for the borders of the ListView.
*/
final int ROW_HEIGHT = 24;
final ObservableList items = FXCollections.observableArrayList("1", "2", "3");
final ListView list = new ListView(items);
// This sets the initial height of the ListView:
list.setPrefHeight(items().size() * ROW_HEIGHT + 2);
Run Code Online (Sandbox Code Playgroud)
现在我们必须将一个ListChangeListener添加到ObservableList.当列表更改时,我们只需更改ListView的设置高度以匹配新的行数.如果我们知道我们永远不会在支持ListView的ObservableList中添加或删除项目,那么我们可以排除侦听器.同样,高度是行数乘以每行的高度加上两个额外的边框像素:
/*
* This listener will resize the ListView when items are added or removed
* from the ObservableList that is backing the ListView:
*/
items.addListener(new ListChangeListener() {
@Override
public void onChanger(ListChangeListener.Change change) {
list.setPrefHeight(items.size() * ROW_HEIGHT + 2);
}
});
Run Code Online (Sandbox Code Playgroud)
参考资料: JavaFX ListView文档,JavaFX ObservableList文档
我刚刚发现Paul Marshall的答案可以使用Bindings.size缩减为单行,它创建一个表示ObservableList大小的数字jfx属性:
listView.prefHeightProperty().bind(Bindings.size(itemListProperty).multiply(LIST_CELL_HEIGHT));
Run Code Online (Sandbox Code Playgroud)
遗憾的是,列表单元格高度仍然是硬编码的AFAIK.