我有这个音乐播放应用程序,可以在网格中显示艺术家和专辑。我使用ListView和自定义ListCells创建了这个网格。但是,ListView在初始化时似乎不会渲染超过2个单元格,即使它的高度足以渲染3行或4行,具体取决于屏幕的大小。但是,当前两个单元格中的一个悬停时,ListView会渲染剩余的单元格。请查看下面的链接,了解实际问题。
我已经检查了ListView的高度,它确实正在扩展以填充其父级,因此我相信ListView决定需要渲染哪些单元格的方式有一些时髦。我希望找到一种方法来强制ListView呈现正确数量的单元格(如果这是潜在的问题),或者如果我的代码中存在错误,那么对它也有一些亮点也很好。我已经在下面发布了我的控制器和自定义ListCell的代码。
初始化ListView的控制器:
public class ArtistsController implements Initializable {
@FXML
private ListView<ArrayList<Artist>> grid;
@Override
public void initialize(URL location, ResourceBundle resources) {
List<Artist> artists = Library.getArtists();
Collections.sort(artists);
grid.setCellFactory(x -> new ArtistListCell<>());
ObservableList<ArrayList<Artist>> rows = FXCollections.observableArrayList();
ArrayList<Artist> row = new ArrayList<>();
int col;
for (int i = 0; i < artists.size(); i++) {
col = i % 5;
if (col == 0) {
row = new ArrayList<>();
rows.add(row);
}
row.add(artists.get(i));
}
grid.setItems(rows);
}
}
自定义ListCell:
public class ArtistListCell<T extends ArrayList<Artist>> extends ListCell<T> {
private T item;
public ArtistListCell() {
this.getStyleClass().setAll("artist-list-cell");
}
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else if (!item.equals(this.item)) {
this.item = item;
HBox row = new HBox();
item.forEach(artist -> {
VBox cell = createCell(artist);
row.getChildren().add(cell);
});
setGraphic(row);
}
}
private VBox createCell(Artist artist) {
VBox cell = new VBox();
Label title = new Label(artist.getTitle());
ImageView image = new ImageView(artist.getArtistImage());
image.imageProperty().bind(artist.artistImageProperty());
VBox imageBox = new VBox();
title.setTextOverrun(OverrunStyle.CLIP);
title.setWrapText(true);
title.setPadding(new Insets(10, 0, 10, 0));
title.setAlignment(Pos.TOP_LEFT);
title.setPrefHeight(66);
title.prefWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
image.fitWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
image.fitHeightProperty().bind(this.widthProperty().subtract(102).divide(5));
image.setPreserveRatio(true);
image.setSmooth(true);
imageBox.prefWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
imageBox.prefHeightProperty().bind(this.widthProperty().subtract(102).divide(5));
imageBox.setAlignment(Pos.CENTER);
imageBox.getChildren().add(image);
cell.getChildren().addAll(imageBox, title);
cell.setPadding(new Insets(10, 10, 0, 10));
cell.getStyleClass().add("artist-cell");
cell.setAlignment(Pos.CENTER);
cell.setOnMouseClicked(event -> {
// do something
});
cell.setOnDragDetected(event -> {
// do something
});
return cell;
}
}
答案 0 :(得分:0)
我整理了一个测试,并使用一个静态图像为艺术家体验了这个问题。如果我用一个简单的矩形替换了ListCell中的行构建它可以正常工作,那么瓶颈似乎是构建你的HBox / VBox单元。
在grid.setItems之后将调用移动到setCellFactory似乎解决了它。
grid.setItems(rows);
grid.setCellFactory(x -> new ArtistListCell<>());
我会说这样做是为了调用另一个布局传递,而另一种方式是没有正确计算所需的所有信息?
如果花费时间,您可能会使用正确的图像加载获得不同的结果。如果是这样,如果您还在使用它,可能会使用占位符图像?