【发布时间】:2019-12-26 18:36:53
【问题描述】:
我正在尝试执行ListView,其中选定的单元格具有不同的用户界面(分别具有不同的高度)。单元格在FXML 中声明,并创建自定义控件(DisplayRowDefault 和DisplayRowSelected)以加载相应的FXML 文件。
我还设置了一个单元格工厂,我在其中管理单元格的渲染,具体取决于它是否被选中。
listView.setCellFactory(lv -> new ListCell<>() {
private DisplayRowSelected selectedGraphics;
private DisplayRowDefault defaultGraphics;
{
defaultGraphics = new DisplayRowDefault();
selectedGraphics = new DisplayRowSelected();
}
@Override
protected void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if(empty || item == null) {
setContentDisplay(ContentDisplay.TEXT_ONLY);
setGraphic(null);
}
else {
selectedGraphics.setIndex(getListView().getItems().indexOf(item));
selectedGraphics.setItem(item);
setGraphic(isSelected() ? selectedGraphics : defaultGraphics);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}
);
除了单元格大小保持不变外,一切都“完美”。
编辑:我找到了解决问题的方法。当覆盖computePrefHeight 单元格被正确调整大小时。此方法的缺点是 prefHeight 必须明确指定。
listView.setCellFactory(lv -> new ListCell<>() {
private DisplayRowSelected selectedGraphics;
private DisplayRowDefault defaultGraphics;
{
defaultGraphics = new DisplayRowDefault();
defaultGraphics.setPrefHeight(50);
selectedGraphics = new DisplayRowSelected();
selectedGraphics.setPrefHeight(100);
}
@Override
protected void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if(empty || item == null) {
setContentDisplay(ContentDisplay.TEXT_ONLY);
setGraphic(null);
}
else {
selectedGraphics.setIndex(getListView().getItems().indexOf(item));
selectedGraphics.setItem(item);
setGraphic(isSelected() ? selectedGraphics : defaultGraphics);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
setPrefHeight(Region.USE_COMPUTED_SIZE);
}
@Override
protected double computePrefHeight(double v) {
if(getContentDisplay() == ContentDisplay.GRAPHIC_ONLY) {
return isSelected() ? selectedGraphics.getPrefHeight() : defaultGraphics.getPrefHeight();
}
return super.computePrefHeight(v);
}
}
);
编辑: MCVE
public class Sample extends Application {
private class SelectedCell extends VBox {
public SelectedCell() {
getChildren().add(new Label("---"));
getChildren().add(new Label("Selected Cell"));
getChildren().add(new Label("---"));
}
}
private class DefaultCell extends VBox {
public DefaultCell() {
getChildren().add(new Label("Default Cell"));
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
List<String> items = List.of("Item A", "Item B", "Item C", "Item D");
ListView<String> listView = new ListView<>();
listView.getItems().setAll(items);
listView.setCellFactory(lv -> new ListCell<>() {
private SelectedCell selectedCell = new SelectedCell();
private DefaultCell defaultCell = new DefaultCell();
@Override
protected void updateItem(String s, boolean b) {
super.updateItem(s, b);
if(s == null || b) {
setContentDisplay(ContentDisplay.TEXT_ONLY);
setGraphic(null);
}
else {
setGraphic(isSelected() ? selectedCell : defaultCell);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
});
Scene scene = new Scene(listView, 200, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
}
【问题讨论】:
-
我没有深究,但表面上看来this可能会有所帮助。
-
@kleopatra,准备好了