Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
Cómo paginar datos de servidor en una lista virtual
Propósito. Mostrar un conjunto de datos grande cuya fuente está paginada (ej.: API REST) sin
cargar todo de una vez. El PagedDataAdapter mantiene una caché LRU de páginas: solo un número
limitado de páginas queda en memoria; al desplazarse a una región cuyos datos fueron descartados, un
spinner aparece y la página se recarga mediante loadPage. El scroll se bloquea mientras la página
carga.
APIs usadas
abstract class PagedDataAdapter(int pageSize, int maxCachedPages)—pageSizeelementos por página; como máximomaxCachedPagespáginas en memoria (LRU). ImplementaVirtualListView.DataAdapter.abstract int getTotalCount()— total de elementos en el servidor (se convierte en elgetCount()de la lista).abstract void loadPage(int pageIndex, PageCallback callback)— carga una página de forma asíncrona; al terminar, llama acallback.onPageLoaded(pageIndex, items). Puede ser llamado desde cualquier thread — la lista hace el switch a la UI.abstract Component createView() throws Exception— crea la view en blanco reutilizable.abstract void bindItem(Component view, Object item, int index) throws Exception— puebla la view con el objeto del elemento (no el texto). A diferencia delbindViewcrudo: aquí recibes el elemento ya resuelto por la página.interface PageCallback { void onPageLoaded(int pageIndex, Object[] items); }PagedDataAdapter.isAvailable(int index)— true si el índice ya está en la caché.PagedDataAdapter.clearCache()— limpia caché y estado de loading.
Ejemplo completo (copiar, pegar y ejecutar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*; // Relative (para VirtualListView)
/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
/** Ítem de negocio simulado — cámbialo por tu entidad real. */
static class Registro
{
final String nome;
Registro(String nome) { this.nome = nome; }
String getNome() { return nome; }
}
static final int totalNoServidor = 12345; // ej.: metadata de la API
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
PagedDataAdapter adapter = new PagedDataAdapter(20, 5) // 20 ítems/página, 5 páginas en memoria
{
public int getTotalCount()
{
return totalNoServidor;
}
public void loadPage(int pageIndex, PageCallback callback)
{
// asíncrono: aquí simulamos la respuesta del servidor en background
onUI(() ->
{
Object[] registros = new Object[20];
for (int i = 0; i < registros.length; i++)
registros[i] = new Registro("Item " + (pageIndex * 20 + i));
callback.onPageLoaded(pageIndex, registros);
});
}
public Component createView() throws Exception
{
return new Label(""); // fila simple reutilizable
}
public void bindItem(Component view, Object item, int index) throws Exception
{
Registro r = (Registro) item; // el ítem ya resuelto de la página
((Label) view).setText(r.getNome());
}
};
// PagedDataAdapter es un DataAdapter: pásalo directo al VirtualListView
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), adapter);
add(LAY_FILL, lista);
}
}
El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colócalo en el esqueleto
MainWindowde arriba.
Fragmento mínimo
// verificado en la fuente: PagedDataAdapter.java
PagedDataAdapter adapter = new PagedDataAdapter(20, 5) // 20 ítems/página, 5 páginas en memoria
{
public int getTotalCount()
{
return totalNoServidor; // ej.: 12345 (viniendo de metadata de la API)
}
public void loadPage(int pageIndex, PageCallback callback)
{
// asíncrono: dispara la petición y responde por el callback
api.buscarPagina(pageIndex, 20, registros ->
callback.onPageLoaded(pageIndex, registros)); // registros = Object[]
}
public Component createView() throws Exception
{
return new Label(""); // fila simple reutilizable
}
public void bindItem(Component view, Object item, int index) throws Exception
{
Registro r = (Registro) item; // el ítem ya resuelto de la página
((Label) view).setText(r.getNome());
}
};
// PagedDataAdapter es un DataAdapter: pásalo directo al VirtualListView
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), adapter);
layout.add(1f, lista);
Profundiza
- El
VirtualListViewse enlaza al adapter automáticamente en el constructor (adapter.listView = this) — no hace falta amarrarlo manualmente. - Mientras
loadPageestá en vuelo, el adapter marcawaitingForDatay elVirtualListViewbloquea pan/fling/wheel y pausa el fling actual (retomado al llegar la página). - Para scroll infinito por append (sin caché LRU), mira carregar-mais.md.
- Guía del widget: PagedDataAdapter · Buenas prácticas: Rendimiento y listas grandes · Fuente canónica: Capítulo 15
¿Te resultó útil esta página?¡Gracias por tu opinión!