As listas e cuadrículas son compoñentes esenciais en calquera aplicación móbil, xa que permiten mostrar grandes cantidades de datos dun xeito organizado e eficiente. Flutter ofrécenos varios widgets para xestionalos.
📃 ListView básico e con builder
ListView é o widget máis común para mostrar unha lista lineal de elementos desprazables. É perfecto para mostrar elementos que cambian dinamicamente ou que son demasiados para caber nunha soa pantalla.
Existen dúas formas principais de usar ListView:
- Lista estática:
ListView - Lista dinámica:
ListView.builder
✅ Lista simple (estática)
Úsase cando tes un número pequeno e fixo de elementos que sabes de antemán. Carga todos os elementos na memoria á vez, o que pode ser ineficiente para listas moi longas.
ListView(
children: [
ListTile(title: Text('Elemento 1')),
ListTile(title: Text('Elemento 2')),
ListTile(title: Text('Elemento 3')),
],
)
🧪 Exemplo
🔁 Lista dinámica con ListView.builder
Esta é a forma preferida para listas grandes ou infinitas. Constrúe os elementos da lista só cando son visibles na pantalla, o que o fai moito máis eficiente en canto a rendemento e consumo de memoria.
Máis eficiente cando hai moitos elementos:
class ListaUsuarios extends StatelessWidget {
final List<String> nomes = ['Ana', 'Brais', 'Carlos', 'Diana'];
@override
Widget build(BuildContext contexto) {
return ListView.builder(
itemCount: nomes.length,
itemBuilder: (contexto, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text(nomes[index]),
);
},
);
}
}
🧪 Exemplo
🧱 GridView
GridView permite mostrar elementos nunha reixa (cuadrícula), útil para galería de imaxes, paneis de iconas ou calquera deseño que se beneficie dunha disposición de tipo reixa.
Do mesmo xeito que ListView, GridView tamén ten construtores para diferentes escenarios:
GridView.count: Permíteche especificar o número fixo de columnas que queres na túa cuadrícula.GridView.extent: Permíteche especificar o ancho máximo de cada elemento da cuadrícula, e o número de columnas axústase automaticamente.GridView.builder: A mellor opción para cuadrículas grandes ou infinitas, xa que constrúe os elementos dinamicamente.
🧪 Exemplo con GridView.count
GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
padding: EdgeInsets.all(8),
children: List.generate(6, (index) {
return Container(
color: Colors.teal[100 * (index % 9)],
child: Center(
child: Text(
'Elemento ${index + 1}',
style: TextStyle(fontSize: 18),
),
),
);
}),
)
🧪 Outro exemplo con GridView.count
import 'package:flutter/material.dart';
class PaginaCuadricula extends StatelessWidget {
@override
Widget build(BuildContext contexto) {
return Scaffold(
appBar: AppBar(
title: Text('Cuadrícula de Elementos'),
),
body: GridView.count(
crossAxisCount: 2, // 2 columnas por fila
crossAxisSpacing: 10, // Espazo horizontal entre elementos
mainAxisSpacing: 10, // Espazo vertical entre elementos
padding: const EdgeInsets.all(10),
children: List.generate(8, (indice) {
return Container(
color: Colors.teal[100 * (indice % 9)], // Cores variadas
child: Center(
child: Text(
'Caixa ${indice + 1}',
style: TextStyle(fontSize: 20, color: Colors.white),
),
),
);
}),
),
);
}
}
🧹 Dismissible
Dismissible permite que un elemento poida ser eliminado deslizándoo cara un lado. É útil para listas onde o usuario poida borrar elementos facilmente.
Para que Dismissible funcione correctamente, cada elemento debe ter unha key única e debes xestionar o que sucede cando o elemento é descartado (por exemplo, eliminalo da túa lista de datos).
🧪 Exemplo
class ListaEliminable extends StatefulWidget {
@override
State<ListaEliminable> createState() => _ListaEliminableState();
}
class _ListaEliminableState extends State<ListaEliminable> {
List<String> tarefas = ['Mercar pan', 'Estudar Flutter', 'Xogar fútbol'];
@override
Widget build(BuildContext contexto) {
return ListView.builder(
itemCount: tarefas.length,
itemBuilder: (contexto, index) {
final tarefa = tarefas[index];
return Dismissible(
key: Key(tarefa),
onDismissed: (direccion) {
setState(() {
tarefas.removeAt(index);
});
ScaffoldMessenger.of(contexto).showSnackBar(
SnackBar(content: Text('Eliminado: $tarefa')),
);
},
background: Container(color: Colors.red),
child: ListTile(
title: Text(tarefa),
),
);
},
);
}
}