Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
ListView
ListView es una lista desplazable de ítems de texto para selección, lista para embeber en cualquier container. Cada ítem se convierte en un “card” clicable. El modo de selección se fija en el constructor vía ItemType: SINGLE (tocar selecciona y confirma) o MULTIPLE (checkboxes + botón “Confirmar”).
A diferencia de VirtualListView, el ListView crea un componente por ítem (sin reciclaje) — es ideal para listas pequeñas/medianas (decenas de ítems), no para miles de filas.
🟡 · Paquete:
dev.crossfly.ui· Extiende:Component· Estilo:ListViewStyle(ítems/header/botón) +WindowStyle(fondo, víaselectionWindowStyle())
Cuándo usar
- Un selector embebido en una pantalla (menú de opciones, filtros, elección de categoría).
- Pocas decenas de ítems de texto donde la altura exacta sin desplazamiento es útil (
computeIdealHeight). - Multi-selección con confirmación explícita (
MULTIPLE).
Cuándo NO usar
- Listas grandes (cientos/miles) → usa
VirtualListView, que recicla componentes. - Popup modal de elección → usa
ListViewWindow, que envuelve elListViewen unaWindow. - Filas ricas con imagen/varios campos → usa
itemFactory(...)o monta la lista a mano con ítems de lista.
Apariencia
Columna vertical de cards de texto centrados, con encabezado opcional (título + ícono de volver) y, en MULTIPLE, un botón “Confirmar” en el pie. En SINGLE cada card es un LabelItem; en MULTIPLE, un CheckLabelItem (checkbox + label).
Ejemplo completo (copiar, pegar y ejecutar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
ListView list = new ListView(new String[]{"Um", "Dois", "Três"}, ListView.ItemType.SINGLE)
.showHeader(false);
list.onConfirm(e -> System.out.println("Escolhido: " + list.getSelectedText()));
add(LAY_FILL, list); // las listas usan LAY_FILL (absorben la altura)
}
}
Los fragmentos de abajo muestran solo el núcleo (lo que va dentro de
onShow()). Para ejecutar, colócalos en el esqueletoMainWindowde arriba.
Uso básico
// SINGLE, sin encabezado, altura automática (sin scroll)
ListView list = new ListView(new String[]{"Um", "Dois", "Três"}, ListView.ItemType.SINGLE)
.showHeader(false);
list.onConfirm(e -> System.out.println("Escolhido: " + list.getSelectedText()));
contents.add(.95f, list);
Constructores
| Constructor | Descripción |
|---|---|
ListView(String[] items, ItemType itemType) |
Lista sin título |
ListView(String title, String[] items, ItemType itemType) |
Lista con título en el encabezado |
ItemType (definido en UIConstants): SINGLE o MULTIPLE. El modo es inmutable tras la construcción.
Propiedades y personalización
| Propiedad / método | Tipo | Por defecto | Qué hace |
|---|---|---|---|
addItem(String) |
ListView |
— | Agrega un ítem (rebuild perezoso; ignora null) |
addItems(String...) |
ListView |
— | Agrega varios ítems (una sola invalidación) |
showHeader(boolean) |
ListView |
true |
Muestra/oculta el encabezado (título + volver) |
title(String) |
ListView |
null |
Define el título |
confirmText(String) |
ListView |
"Confirmar" |
Texto del botón (solo MULTIPLE) |
itemStyle(ComponentStyle) |
ListView |
tema | Override de estilo de todos los ítems |
confirmButtonStyle(ComponentStyle) |
ListView |
tema | Estilo del botón de confirmar |
headerStyle(LabelStyle) |
ListView |
tema | Estilo del encabezado |
itemFactory(ItemFactory) |
ListView |
null |
Fábrica de ítem personalizado (recibe text, index) |
closeAction(Runnable) |
ListView |
null |
Acción de cierre (la ListViewWindow apunta a this::hide) |
computeIdealHeight(int width) |
int |
— | Altura exacta sin desplazamiento, o -1 si hay itemFactory |
Consulta de selección
getSelectedCount(), getSelectedIndex(), getSelectedText(), getSelectedIndices(), getSelectedTexts(), isSelected(int), getSelectionState() (boolean[]).
Callbacks y eventos
| Callback | Cuándo se dispara |
|---|---|
onConfirm(Component.Action) |
SINGLE: al tocar un ítem. MULTIPLE: al tocar “Confirmar” |
En SINGLE, el toque limpia la selección anterior, marca el índice, dispara onConfirm y llama a close(). En MULTIPLE, el toque alterna el checkbox del ítem; la confirmación sale del botón.
Estados
- SINGLE — solo un ítem marcado a la vez; el toque ya confirma y cierra.
- MULTIPLE — varios ítems marcables; estado consultable vía
getSelectionState()incluso antes de confirmar. - El encabezado y el botón de pie son opcionales (dependen de
showHeader/titley delItemType).
MULTIPLE con altura automática
ListView multi = new ListView(new String[]{"Vermelho", "Verde", "Azul"},
ListView.ItemType.MULTIPLE)
.showHeader(false)
.confirmText("Aplicar");
multi.getStyle().autoHeight(Relative.ofFont(9f));
multi.onConfirm(e -> {
for (String t : multi.getSelectedTexts())
System.out.println("marcado: " + t);
});
contents.add(.95f, multi);
Filas personalizadas con itemFactory
ListView list = new ListView(labels, ListView.ItemType.SINGLE).showHeader(false);
list.itemFactory((text, index) -> {
Component row = new Component();
row.style(Styles.component().pressable().ingap(Gap.ofFont(.3f)));
row.setLayout(new GridLayout(Position.START, Position.CENTER));
row.add(new Label(text));
return row;
});
list.onConfirm(e -> System.out.println("idx = " + list.getSelectedIndex()));
contents.add(.95f, list);
Buenas prácticas
- Prefiere
addItems(...)a variosaddItem(...)— una única invalidación de layout. - Usa
computeIdealHeight(width)cuando quieras una lista sin desplazamiento con altura exacta (devuelve-1si hayitemFactory, pues los ítems personalizados no son medibles genéricamente). - La reconstrucción de los ítems es perezosa (ocurre en el próximo layout), incluso cuando el ancho cambia.
Errores comunes
- Usar
ListViewpara miles de ítems — no recicla; la memoria crece linealmente. Migra aVirtualListView. - Esperar
onConfirmenMULTIPLEa cada toque — enMULTIPLEel callback solo se dispara en el botón “Confirmar”; consultagetSelectionState()para reaccionar a cada marcación. - Asumir que existe un constructor sin ítems — el constructor exige
itemseItemType; comienza connew String[]{}y usaaddItems(...).
Ver también
- Guía del área:
ui/· Recetas:cookbook/ - Componentes relacionados:
ListViewWindow·VirtualListView· ítems de lista (LabelItem/CheckLabelItem)