有没有办法检测屏幕上显示的单元格?

时间:2016-09-05 02:35:48

标签: gridview tableview javafx-8

我正在使用TableViewGridView的媒体播放器。由于一旦加载大量数据,一次加载所有用户的音乐并不能很好地执行,我想尽可能地延迟加载。我想为此做的一件事是延迟加载音乐文件,直到它们在屏幕上可见。由于TableView和GridView都使用单元格,我想知道是否有办法确定屏幕上是否显示了单元格。

1 个答案:

答案 0 :(得分:0)

经过一番研究后,我设法得到了一些有用的东西。首先,这是我用来从GridView和TableView获取可见项的两个函数。

public static <T> List<T> getVisible(GridView<T> gridView)
{
    List<T> retList = new ArrayList<>();
    GridViewSkin<?> skin = (GridViewSkin<?>) gridView.getSkin();
    VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().stream().filter(n -> n instanceof VirtualFlow).findFirst().get();

    int firstIndex = flow.getFirstVisibleCell().getIndex();
    int lastIndex = flow.getLastVisibleCell().getIndex();
    int cellsInRow = skin.computeMaxCellsInRow();

    retList.addAll(gridView.getItems().subList(firstIndex * cellsInRow, Math.min((lastIndex + 1) * cellsInRow, gridView.getItems().size())));
    return retList;
}

public static <T> List<T> getVisible(TableView<T> tableView)
{
    List<T> retList = new ArrayList<>();
    TableViewSkin<?> skin = (TableViewSkin<?>) tableView.getSkin();
    VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().stream().filter(n -> n instanceof VirtualFlow).findFirst().get();

    int firstIndex = flow.getFirstVisibleCell().getIndex();
    int lastIndex = flow.getLastVisibleCell().getIndex();

    retList.addAll(tableView.getItems().subList(firstIndex, lastIndex + 1));
    return retList;
}

它们基本相同,但GridView实际上是由行对象组成的,所以我需要乘以每行的单元格数,以获得单元格的实际索引。

GridView和TableView的下一部分完全相同。我设置了一个事件监听器,它监听所有事件,然后对可见项执行我想要的任何操作。

TABLE_OR_GRID_VIEW.addEventHandler(EventType.ROOT, evt -> {
    List<ITEM> items = getVisible(TABLE_OR_GRID_VIEW);
    // do whatever you want with the visible items here.
});