Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar

Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.

Rendimiento y listas grandes

Cómo mantener 60 fps — incluso en GPU low-end — con muchos datos o dibujo pesado. El “porqué” (paint thread única, render bajo demanda) está en La paint thread y El pipeline de renderizado.

Virtualiza: VirtualListView, no ListView

ListView mantiene todos los ítems en memoria. Para cientos/miles, usa VirtualListView — él recicla vistas (renderiza solo lo visible). El adapter separa crear (una vez, reciclado) de vincular (barato, se ejecuta mucho):

VirtualListView lista = new VirtualListView(Relative.ofFont(3f), new DataAdapter() {
   public int getCount() { return dados.size(); }
   public Component createView() throws Exception {         // creado pocas veces (pool)
      return new Label("");
   }
   public void bindView(Component v, int i) throws Exception {  // corre MUCHO en el scroll → barato e idempotente
      ((Label) v).setText(dados.get(i).nome);
   }
});
// al cambiar los datos:
lista.notifyDataChanged();

bindView debe ser barato e idempotente — se ejecuta en cada reciclaje al hacer scroll. Nada de I/O, asignación ni cálculo caro ahí.

Por qué reciclar: el costo real es createView(). Reciclando, la memoria queda constante independientemente de getCount() — 10 o 10.000 ítems usan el mismo puñado de vistas.

Paginación remota: PagedDataAdapter

Para datos que llegan por página (red), usa PagedDataAdapter (caché LRU interna):

var adapter = new PagedDataAdapter(50, 4) {   // 50 ítems/página, 4 páginas en caché
   public int getTotalCount() { return total; }
   public void loadPage(int page, PageCallback cb) {
      new Thread(() -> {
         Object[] itens = api.buscarPagina(page, pageSize);   // fuera de la paint thread
         Component.onUI(() -> cb.onPageLoaded(page, itens));   // vuelve a la UI
      }).start();
   }
   public Component createView() throws Exception { return new Label(""); }
   public void bindItem(Component v, Object item, int i) throws Exception {
      ((Label) v).setText(((Cliente) item).nome);
   }
};

Dibujo: onPaint barato y render bajo demanda

  • No repintes por frame. Llama a repaint() solo cuando el estado cambia — la pantalla no se redibuja sola (render bajo demanda).
  • No asignes en onPaint. Se ejecuta para el árbol entero en cada frame; reutiliza objetos (GRect, Font) en campos, no los crees por frame.
  • Nunca bloquees la paint thread — I/O de base de datos/red en thread de trabajo + onUI.

Buenas prácticas

  • VirtualListView a partir de ~cientos de ítems; ListView solo para listas pequeñas/fijas.
  • bindView/bindItem ligeros; carga imágenes/datos fuera y vincula lo ya-listo.
  • Imágenes grandes: redimensiona una vez (escala destructiva) en vez de escalar por frame.

Errores comunes

  • ListView con miles de ítems (agota memoria / se traba).
  • bindView haciendo I/O o asignando (atasca el scroll).
  • Repintar en loop/por frame en vez de bajo demanda.

Ver también

¿Te resultó útil esta página?