📋 Unha lista que permite desprazarse
ListView organiza os elementos nunha lista vertical con desprazamento. Colocámola, por exemplo, no body do Scaffold.
ListTile representa unha fila habitual: pode levar unha icona en leading, un texto en title, outro en subtitle e un widget á dereita en trailing.
📝 Poucos elementos: ListView
ListView(
children: const [
ListTile(
leading: Icon(Icons.person),
title: Text('Xurxo'),
subtitle: Text('2º DAM'), // Información secundaria.
),
ListTile(leading: Icon(Icons.person), title: Text('Iria'), subtitle: Text('2º DAM')),
ListTile(leading: Icon(Icons.person), title: Text('Iago'), subtitle: Text('2º DAM')),
ListTile(leading: Icon(Icons.person), title: Text('Anxo'), subtitle: Text('2º DAM')),
],
)
Nesta variante proporcionamos xa a lista de widgets. Para moitos elementos, é preferible crealos a medida que fan falta.

🏗️ Crear filas con ListView.builder
O callback itemBuilder recibe o contexto e o índice da fila, empezando en cero. Debe devolver o widget desa fila. Flutter chámao cando necesita construíla, non necesariamente para toda a lista de golpe nin unha única vez.
Fragmento dentro de build, antes de devolver o Scaffold:
final alumnos = ['Xurxo', 'Roi', 'Iria', 'Anxo'];
No body:
ListView.builder(
itemCount: alumnos.length, // Número de filas.
itemBuilder: (context, indice) {
return ListTile(
leading: const Icon(Icons.person),
title: Text(alumnos[indice]), // Consultamos o dato desa posición.
subtitle: const Text('2º DAM'),
);
},
)

➖ Separar as filas: ListView.separated
Funciona igual, pero engade outro callback, separatorBuilder, que devolve o widget situado entre dúas filas.
ListView.separated(
itemCount: alumnos.length,
itemBuilder: (context, indice) {
return ListTile(
leading: const Icon(Icons.person),
title: Text(alumnos[indice]),
subtitle: const Text('2º DAM'),
);
},
separatorBuilder: (context, indice) {
return const Divider(); // Liña entre filas, non despois da última.
},
)

🧪 Un título fixo e unha lista desprazable
Se metemos unha lista nunha Column, temos que darlle unha altura limitada. Neste exemplo, Expanded dálle a altura restante baixo o título.
🔗 DartPad:
| Parámetro | Para que serve? |
|---|---|
padding | Espazo arredor do contido da lista. |
scrollDirection | Dirección do desprazamento; por defecto é vertical. |
itemCount | Número de elementos en builder e separated. |
itemBuilder | Función que constrúe cada fila en builder e separated. |
shrinkWrap: true axusta o tamaño da lista ao contido, pero pode supoñer máis traballo de cálculo. Non é a solución por defecto para unha lista dentro dunha Column: comeza con Expanded cando queiras ocupar a altura restante.

📚 Consulta: