本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
如何实现加载更多(无限滚动)
目的。 在用户接近列表末尾时自动加载更多数据,将项目追加到现有数据集(append)。 与带 LRU 缓存的分页(paginacao.md)不同,这里由你控制数据集, 列表仅在需要获取更多数据时发出通知。
使用的 API
VirtualListView.onLoadMore(Runnable callback)— 当滚动接近末尾时触发。每次只有一个待处理的触发(loadMorePending),避免重复调用。VirtualListView.loadMoreThreshold(int threshold)— 距离末尾多少项时触发回调。默认5。VirtualListView.notifyDataChanged()— 在追加新项后必须调用;它会清除loadMorePending、隐藏加载指示器并重新测量内容。
完整示例(复制、粘贴并运行)
package com.exemplo;
import java.util.*; // List / ArrayList
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*; // Relative(用于 VirtualListView)
/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
final List<String> dados = new ArrayList<>();
int proxima = 0;
/** 向数据集追加一批 30 个项目(模拟服务器返回的一页)。 */
private void carregarPagina()
{
for (int i = 0; i < 30; i++)
dados.add("Registro " + (proxima++));
}
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
carregarPagina(); // 填充第一批
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), new VirtualListView.DataAdapter()
{
public int getCount() { return dados.size(); }
public Component createView() { return new Label(""); }
public void bindView(Component v, int i) throws Exception
{
((Label) v).setText(dados.get(i));
}
});
lista.loadMoreThreshold(8); // 在末尾前 8 项开始拉取(默认为 5)
lista.onLoadMore(() ->
{
// 接近末尾时触发一次;后续触发仅在 notifyDataChanged 之后
onUI(() ->
{
carregarPagina(); // 追加(新索引在末尾)
lista.notifyDataChanged(); // 放行下一次 load-more 并隐藏 spinner
});
});
add(LAY_FILL, lista);
}
}
下面的片段只展示核心部分。要运行它,请将其放入上面的
MainWindow骨架中。
最小片段
// 已在源码核实:VirtualListView.java(onLoadMore / loadMoreThreshold / notifyDataChanged)
final Array<String> dados = new Array<>();
carregarPagina(dados, 0); // 填充第一批
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), new VirtualListView.DataAdapter()
{
public int getCount() { return dados.size(); }
public Component createView() { return new Label(""); }
public void bindView(Component v, int i) throws Exception
{
((Label) v).setText(dados.get(i));
}
});
lista.loadMoreThreshold(8); // 在末尾前 8 项开始拉取(默认为 5)
lista.onLoadMore(() ->
{
// 接近末尾时触发一次;后续触发仅在 notifyDataChanged 之后
api.proximaPagina(novos ->
{
dados.addAll(novos); // 追加(新索引在末尾)
lista.notifyDataChanged(); // 放行下一次 load-more 并隐藏 spinner
});
});
layout.add(1f, lista);
深入了解
VirtualListView在加载更多处于待处理状态时会自动在底部显示加载指示器(由VirtualListViewStyle.showSpinner控制)。- 如果你不调用
notifyDataChanged(),loadMorePending将卡在true,回调将永远不再触发。 - 需要带有限缓存的可丢弃页面(而非无限追加)?使用 paginacao.md。
- 组件指南:VirtualListView · 姊妹配方:lista-virtual-grande.md · 权威来源:第 15 章
这个页面有帮助吗?感谢你的反馈!