CharmListView 无限滚动

CharmListView Infinite Scroll

我基本上需要一个在每加载 200 条记录时触发的事件,以便可以加载更多数据直到数据结束。

我尝试扩展 CharmListCell 并像这样使用方法 updateItem:

@Override
public void updateItem(Model item, boolean empty) {
    super.updateItem(item, empty);
    currentItem = item;
    if (!empty && item != null) {
        update();
        setGraphic(slidingTile);
    } else {
        setGraphic(null);
    }

    System.out.println(getIndex());
}

但是 System.out.println(getIndex()); 方法 returns -1;

我想在向下滚动到最后一个获取块的末尾时调用我的后端方法,依此类推,直到像 "infinite scroll" 技术那样得到数据的末尾。

谢谢!

CharmListCell 不公开底层 listView 的索引,但即使它公开了,如果您滚动到当前列表的末尾,那也没有多大帮助与否。

我建议使用一种不同的方法,它对常规 ListView 也有效,具有 CharmListView 功能的优点(主要是 headers 和刷新指示器) .

这个简短的示例是使用 Gluon IDE plugin 和 Charm 5.0.0 通过单个视图项目创建的,展示了如何创建 CharmListView 控件,并用一次30个项目。我没有提供工厂单元,也没有提供 headers,为了简单起见,我只是添加连续的整数。

通过查找,在视图显示后(因此将 listView 添加到场景中)我们找到 listView 的垂直 ScrollBar,然后我们添加一个侦听器来跟踪它的位置。当它接近 1 时,我们模拟另一批项目的负载,暂停过渡表示任务繁重。

注意刷新指示器的使用。添加新数据时,我们会滚动回第一个新项目,这样我们就可以继续滚动。

public class BasicView extends View {

    private final ObservableList<Integer> data;
    private CharmListView<Integer, Integer> listView;
    private final int batchSize = 30;
    private PauseTransition pause;

    public BasicView() {
        data = FXCollections.observableArrayList();

        listView = new CharmListView<>(data);
        setOnShown(e -> {
            ScrollBar scrollBar = null;
            for (Node bar : listView.lookupAll(".scroll-bar")) {
                if (bar instanceof ScrollBar && ((ScrollBar) bar).getOrientation().equals(Orientation.VERTICAL)) {
                    scrollBar = (ScrollBar) bar;
                    break;
                }
            }
            if (scrollBar != null) {
                scrollBar.valueProperty().addListener((obs, ov, nv) -> {
                    if (nv.doubleValue() > 0.95) {
                        addBatch();
                    }
                });
                addBatch();
            }
        });
        setCenter(new VBox(listView));
    }

    private void addBatch() {
        listView.setRefreshIndicatorVisible(true);
        if (pause == null) {
            pause = new PauseTransition(Duration.seconds(1));
            pause.setOnFinished(f -> {
                int size = data.size();
                List<Integer> list = new ArrayList<>();
                for (int i = size; i < size + batchSize; i++) {
                    list.add(i);
                }
                data.addAll(list);
                listView.scrollTo(list.get(0));
                listView.setRefreshIndicatorVisible(false);
            });
        } else {
            pause.stop();
        }
        pause.playFromStart();
    }
}

另请注意,您可以随时受益于 setOnPullToRefresh() 方法。例如,如果您添加:

listView.setOnPullToRefresh(e -> addBatch());

每当您转到列表顶部并将其向下拖动(在移动设备上)时,它会再次调用以加载新的一批项目。显然,这是与 "infinite scrolling" 相反的行为,但是 CharmListView 控件也是可能的。