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),
),
);
},
);
}
}