Row y Column en Flutter
Domina los widgets fundamentales para organizar tu interfaz de usuario
Descargar Ejemplos Completos¿Qué son Row y Column?
Row y Column son los widgets más importantes en Flutter para organizar otros widgets en la pantalla. Son widgets de diseño flex que organizan a sus hijos en una dirección específica.
Row
Organiza widgets horizontalmente de izquierda a derecha
Column
Organiza widgets verticalmente de arriba a abajo
Sintaxis Básica
Row Básico
Row(
children: [
Text('Elemento 1'),
Text('Elemento 2'),
Text('Elemento 3'),
],
)
Column Básico
Column(
children: [
Text('Elemento 1'),
Text('Elemento 2'),
Text('Elemento 3'),
],
)
Propiedades Principales
mainAxisAlignment
Alineación en el eje principal
crossAxisAlignment
Alineación en el eje cruzado
mainAxisSize
Tamaño en el eje principal
mainAxisAlignment
Controla cómo se distribuyen los widgets a lo largo del eje principal (horizontal para Row, vertical para Column).
Ejemplos en Row:
MainAxisAlignment.start
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
Código de Ejemplo:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
)
crossAxisAlignment
Controla cómo se alinean los widgets en el eje cruzado (vertical para Row, horizontal para Column).
Ejemplos en Column:
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.stretch
Ejemplos Prácticos
1. Barra de Navegación Superior
Row(
children: [
IconButton(icon: Icon(Icons.menu), onPressed: () {}),
Expanded(
child: Text('Mi Aplicación', textAlign: TextAlign.center),
),
IconButton(icon: Icon(Icons.search), onPressed: () {}),
IconButton(icon: Icon(Icons.settings), onPressed: () {}),
],
)
2. Tarjeta de Perfil
Row(
children: [
CircleAvatar(backgroundImage: NetworkImage(url)),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Juan Pérez', style: TextStyle(fontWeight: FontWeight.bold)),
Text('juan@email.com'),
],
),
),
Icon(Icons.chevron_right),
],
)
3. Formulario de Login
Column(
children: [
TextField(decoration: InputDecoration(labelText: 'Email')),
SizedBox(height: 16),
TextField(decoration: InputDecoration(labelText: 'Contraseña'), obscureText: true),
SizedBox(height: 24),
Row(
children: [
Expanded(child: TextButton(child: Text('Cancelar'), onPressed: () {})),
SizedBox(width: 16),
Expanded(child: ElevatedButton(child: Text('Iniciar Sesión'), onPressed: () {})),
],
),
],
)
Probador de Row y Column
// El código se generará aquí
Row vs Column - ¿Cuándo usar cada uno?
| Aspecto | Row | Column |
|---|---|---|
| Dirección | Horizontal | Vertical |
| Eje Principal | Horizontal | Vertical |
| Eje Cruzado | Vertical | Horizontal |
| Casos de Uso | Barras de navegación, filas de datos, botones en línea | Formularios, listas, páginas de scroll vertical |
| Ejemplo | Icono + Texto + Botón | Título + Imagen + Descripción + Botón |
Widgets Hijos Especiales
Errores Comunes y Soluciones
❌ "Vertical viewport was given unbounded height"
Problema: Un Column dentro de un ListView sin altura definida
Solución: Usar SingleChildScrollView o envolver en Expanded
// MAL
ListView(children: [Column(children: [...]))])
// BIEN
SingleChildScrollView(child: Column(children: [...]))
❌ "RenderFlex overflowed by ... pixels"
Problema: Los widgets no caben en la pantalla
Solución: Usar SingleChildScrollView o reducir el contenido
// MAL
Column(children: [/* mucho contenido */])
// BIEN
SingleChildScrollView(child: Column(children: [...]))
❌ Widgets no se alinean correctamente
Problema: crossAxisAlignment mal configurado
Solución: Usar CrossAxisAlignment.stretch o definir anchos
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(height: 50, color: Colors.red),
Container(height: 50, color: Colors.blue),
],
)
Consejos y Mejores Prácticas
🎯 Usa SizedBox para espaciado
En lugar de Padding para separar widgets, usa SizedBox que es más eficiente:
Column(
children: [
Text('Título'),
SizedBox(height: 16), // Mejor que Padding
Text('Subtítulo'),
],
)
📱 Considera responsive design
Usa LayoutBuilder o MediaQuery para adaptar Row/Column a diferentes tamaños de pantalla:
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
return Row(children: [...]); // Tablet
} else {
return Column(children: [...]); // Móvil
}
},
)
⚡ Optimiza con const
Usa const constructores para widgets que no cambian:
Column(
children: const [
Text('Título'),
SizedBox(height: 16),
Text('Subtítulo'),
],
)
Ejercicios para Practicar
Ejercicio 1: Barra de Herramientas
Crea una barra de herramientas con iconos centrados y espacio entre ellos.
Pista: Usa Row con MainAxisAlignment.spaceEvenly
Ejercicio 2: Formulario de Registro
Crea un formulario con campos apilados verticalmente y botones alineados a la derecha.
Pista: Combina Column y Row con CrossAxisAlignment.end
Ejercicio 3: Tarjeta de Producto
Crea una tarjeta con imagen a la izquierda y texto a la derecha que ocupe el espacio restante.
Pista: Usa Row con Expanded alrededor del texto