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

1
2
3

Column

Organiza widgets verticalmente de arriba a abajo

1
2
3

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

start end center spaceBetween spaceAround spaceEvenly

crossAxisAlignment

Alineación en el eje cruzado

start end center stretch

mainAxisSize

Tamaño en el eje principal

max min

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
Inicio
A
B
C
Fin
MainAxisAlignment.center
Inicio
A
B
C
Fin
MainAxisAlignment.spaceBetween
Inicio
A
B
C
Fin

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
Inicio
A
B
C
Fin
CrossAxisAlignment.center
Inicio
A
B
C
Fin
CrossAxisAlignment.stretch
Inicio
A
B
C
Fin

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

👤
Juan Pérez
juan@email.com
➡️
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

3 widgets
1
2
3
// 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

Expanded

Ocupa el espacio disponible en el eje principal

Fijo
Expandido
Fijo
Row( children: [ Container(width: 50, color: Colors.red), Expanded( child: Container(color: Colors.blue), ), Container(width: 50, color: Colors.green), ], )

Flexible

Similar a Expanded pero con flex personalizado

Flex 2
Flex 1
Flex 1
Row( children: [ Flexible(flex: 2, child: Container(color: Colors.red)), Flexible(flex: 1, child: Container(color: Colors.green)), Flexible(flex: 1, child: Container(color: Colors.blue)), ], )

Spacer

Crea espacio flexible entre widgets

Inicio
Fin
Row( children: [ Text('Inicio'), Spacer(), Text('Fin'), ], )

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