Ir al contenido

Guía de Flutter para novatos - Miguel Páramos

FAQ sobre Flutter pal que no tiene ni idea de Flutter | 2º DAM · PMDM

Catálogo de ejemplos prácticos con los 7 widgets fundamentales en el body (con 1 y con varios elementos)

A la hora de estructurar el área de contenido (body) de una pantalla en Flutter, existen siete widgets fundamentales de maquetación. En Flutter, los widgets de layout se clasifican principalmente en dos categorías:

  • Single-child widgets: admiten exclusivamente un único widget en su propiedad child:. Para alojar varios elementos en su interior, se anida un widget contenedor de múltiples hijos (como Column o Row) dentro de su child.
  • Multi-child widgets: admiten directamente una lista de widgets en su propiedad children: <Widget>[ ... ].

A continuación se presentan ejemplos prácticos y concisos de cada uno de los siete widgets fundamentales, mostrando cómo implementar tanto un único elemento como múltiples componentes:

// Ejemplo con 1 elemento:
body: const Center( // Widget que centra geométricamente a su hijo único
child: Text('Un solo texto centrado'), // Componente de texto centrado en pantalla
) // Fin del widget Center
// Ejemplo con varios elementos (usando Column como puente):
body: const Center( // Centra el contenedor completo en la pantalla
child: Column( // Disposición vertical que agrupa múltiples elementos
mainAxisSize: MainAxisSize.min, // Ajusta la altura de la columna al tamaño mínimo de sus hijos
children: [ // Lista de widgets apilados verticalmente
Text('Título centrado'), // Primer texto centrado
Text('Subtítulo centrado'), // Segundo texto centrado
], // Fin de la lista children
), // Fin de Column
) // Fin del widget Center

2. Column (Distribuye verticalmente de arriba a abajo)

Sección titulada «2. Column (Distribuye verticalmente de arriba a abajo)»
// Ejemplo con 1 elemento:
body: const Column( // Columna que organiza elementos en el eje vertical
children: [ // Lista de componentes hijos
Text('Solo un elemento en la columna'), // Único texto ubicado al inicio vertical
], // Fin de la lista children
) // Fin de Column
// Ejemplo con varios elementos:
body: Column( // Columna vertical interactiva
children: [ // Lista de widgets en cascada vertical
const Text('Elemento 1'), // Texto estático en la primera posición
const Icon(Icons.star, color: Colors.amber), // Icono decorativo de estrella dorada
ElevatedButton(onPressed: () {}, child: const Text('Botón 3')), // Botón interactivo en tercera posición
], // Fin de la lista children
) // Fin de Column

3. Row (Distribuye horizontalmente de izquierda a derecha)

Sección titulada «3. Row (Distribuye horizontalmente de izquierda a derecha)»
// Ejemplo con 1 elemento:
body: const Row( // Fila que organiza elementos horizontalmente de izquierda a derecha
children: [ // Lista de widgets hijos
Text('Un solo elemento en fila'), // Único componente de texto en la fila
], // Fin de la lista children
) // Fin de Row
// Ejemplo con varios elementos:
body: Row( // Fila con distribución uniforme en el eje horizontal
mainAxisAlignment: MainAxisAlignment.spaceAround, // Reparte el espacio libre alrededor de cada elemento
children: [ // Componentes alineados en fila
const Icon(Icons.home), // Icono de inicio en primera posición
const Text('Inicio'), // Texto descriptivo intermedio
ElevatedButton(onPressed: () {}, child: const Text('Ir')), // Botón interactivo al final de la fila
], // Fin de la lista children
) // Fin de Row

4. ListView (Lista desplazable, ideal para mucho contenido)

Sección titulada «4. ListView (Lista desplazable, ideal para mucho contenido)»
// Ejemplo con 1 elemento:
body: const ListView( // Lista desplazable que habilita scroll automático
children: [ // Colección de filas de contenido
ListTile(title: Text('Un único elemento de lista')), // Fila con estilo estándar de lista
], // Fin de la lista children
) // Fin de ListView
// Ejemplo con varios elementos:
body: ListView( // Lista con capacidad de desplazamiento vertical para mucho contenido
children: const [ // Lista de elementos inmutables
ListTile(leading: Icon(Icons.person), title: Text('Usuario 1')), // Primer elemento con icono y texto
ListTile(leading: Icon(Icons.person), title: Text('Usuario 2')), // Segundo elemento con icono y texto
ListTile(leading: Icon(Icons.person), title: Text('Usuario 3')), // Tercer elemento con icono y texto
], // Fin de la lista children
) // Fin de ListView

5. GridView (Rejilla o cuadrícula bidimensional)

Sección titulada «5. GridView (Rejilla o cuadrícula bidimensional)»
// Ejemplo con 1 elemento:
body: GridView.count( // Rejilla bidimensional con número fijo de columnas
crossAxisCount: 2, // Cuadrícula organizada en 2 columnas
children: [ // Celdas de la cuadrícula
Container(color: Colors.red, child: const Center(child: Text('Celda 1'))), // Celda única con fondo rojo
], // Fin de la lista children
) // Fin de GridView.count
// Ejemplo con varios elementos:
body: GridView.count( // Cuadrícula con múltiples celdas y espaciado
crossAxisCount: 2, // Distribuye el contenido en 2 columnas
crossAxisSpacing: 8, // Separación horizontal de 8 píxeles entre columnas
mainAxisSpacing: 8, // Separación vertical de 8 píxeles entre filas
children: [ // Celdas con fondos de colores diferentes
Container(color: Colors.red, child: const Center(child: Text('A'))), // Celda A con fondo rojo
Container(color: Colors.green, child: const Center(child: Text('B'))), // Celda B con fondo verde
Container(color: Colors.blue, child: const Center(child: Text('C'))), // Celda C con fondo azul
Container(color: Colors.orange, child: const Center(child: Text('D'))), // Celda D con fondo naranja
], // Fin de la lista children
) // Fin de GridView.count

6. Stack (Superpone capas una encima de otra, eje Z)

Sección titulada «6. Stack (Superpone capas una encima de otra, eje Z)»

(Similar a un FrameLayout o ConstraintLayout superpuesto en Android nativo)

// Ejemplo con 1 elemento:
body: const Stack( // Contenedor que superpone widgets en capas sobre el eje Z
children: [ // Capas superpuestas
Text('Solo un texto en el fondo'), // Capa base única
], // Fin de la lista children
) // Fin de Stack
// Ejemplo con varios elementos (capa sobre capa):
body: Stack( // Pila de capas superpuestas
alignment: Alignment.center, // Centra por defecto las capas no posicionadas
children: [ // Capas ordenadas de fondo a superficie
Container(width: 200, height: 200, color: Colors.blue[100]), // Capa 1 (Fondo): caja cuadrada de 200x200
const Icon(Icons.favorite, size: 80, color: Colors.red), // Capa 2 (Intermedia): icono de corazón centrado
const Positioned( // Capa 3 (Superior): posicionada de forma absoluta
bottom: 10, // Separación de 10 píxeles del borde inferior
right: 10, // Separación de 10 píxeles del borde derecho
child: Text('Capa encima', style: TextStyle(fontWeight: FontWeight.bold)), // Texto superpuesto
), // Fin de Positioned
], // Fin de la lista children
) // Fin de Stack

7. Container (Caja con dimensiones, márgenes, color y bordes)

Sección titulada «7. Container (Caja con dimensiones, márgenes, color y bordes)»

(Similar a un Box en Jetpack Compose o una View con background y padding en XML)

// Ejemplo con 1 elemento:
body: Container( // Caja decorada con dimensiones y márgenes
margin: const EdgeInsets.all(20), // Margen exterior de 20 píxeles alrededor de la caja
padding: const EdgeInsets.all(16), // Relleno interior de 16 píxeles hacia el hijo
color: Colors.amber[200], // Color de fondo ámbar suave
child: const Text('Texto dentro de un contenedor decorado'), // Texto hijo envuelto
) // Fin de Container
// Ejemplo con varios elementos (anidando una Column dentro de su child):
body: Container( // Caja que actúa como tarjeta personalizada
padding: const EdgeInsets.all(20), // Relleno interior de 20 píxeles
decoration: BoxDecoration( // Decoración avanzada con bordes redondeados
color: Colors.teal[50], // Tono de fondo verde azulado suave
borderRadius: BorderRadius.circular(12), // Esquinas redondeadas con radio de 12 píxeles
), // Fin de BoxDecoration
child: const Column( // Agrupa múltiples elementos verticales dentro de la tarjeta
mainAxisSize: MainAxisSize.min, // Se contrae a la altura estricta de sus textos
children: [ // Elementos agrupados en la tarjeta
Text('Título de la tarjeta', style: TextStyle(fontSize: 18)), // Título principal de la tarjeta
SizedBox(height: 8), // Separación vertical de 8 píxeles
Text('Cuerpo de la tarjeta con varios elementos agrupados'), // Texto descriptivo secundario
], // Fin de la lista children
), // Fin de Column
) // Fin de Container