Widgets con Hijos y sin Hijos en Flutter

  Widgets con Hijos y sin Hijos

En Flutter, los widgets se clasifican en dos tipos principales: widgets sin hijos (leaf widgets) que no contienen otros widgets, y widgets con hijos que pueden contener uno o múltiples widgets internos.

Widgets Sin Hijos

Los widgets sin hijos son elementos independientes que no necesitan contener otros widgets para funcionar.

SizedBox

Este widget crea un espacio de tamaño fijo.

dart
SizedBox(
width: 100,
height: 50,
)

// Solo altura
SizedBox(height: 20)

// Solo ancho  
SizedBox(width: 30)

Explicación: SizedBox es perfecto para crear espacios específicos entre widgets o definir dimensiones exactas.

Spacer

Crea un espacio flexible que se expande.

dart
Row(
children: [
  Text('Izquierda'),
  Spacer(), // Se expande para llenar el espacio
  Text('Derecha'),
],
)

Explicación: Spacer empuja los widgets hacia los extremos, ocupando todo el espacio disponible entre ellos.

Divider

Muestra una línea horizontal de separación.

dart
Column(
children: [
  Text('Elemento 1'),
  Divider(
    color: Colors.grey,
    thickness: 2,
  ),
  Text('Elemento 2'),
],
)

Explicación: Divider es ideal para separar visualmente secciones de contenido con una línea horizontal.

VerticalDivider

Línea vertical de separación.

dart
Row(
children: [
  Text('Izquierda'),
  VerticalDivider(
    color: Colors.blue,
    width: 20,
  ),
  Text('Derecha'),
],
)

Explicación: Similar a Divider pero vertical, útil en layouts horizontales como Row.

CircularProgressIndicator

Indicador de carga circular.

dart
CircularProgressIndicator()

// Con color personalizado
CircularProgressIndicator(
color: Colors.blue,
strokeWidth: 6,
)

Explicación: Muestra una rueda de carga giratoria, perfecta para indicar procesos en curso.

LinearProgressIndicator

Barra de progreso horizontal.

dart
LinearProgressIndicator()

// Con progreso específico (0.0 a 1.0)
LinearProgressIndicator(
value: 0.7,
backgroundColor: Colors.grey[300],
color: Colors.green,
)

Explicación: Barra horizontal que muestra el progreso de una tarea, útil para descargas o procesos largos.

Widgets con Un Hijo


A continuación, se presentan algunos widgets con un hijo. Estos widgets pueden contener exactamente un widget hijo.

Container

El widget más versátil para diseño.

dart
Container(
width: 200,
height: 100,
color: Colors.blue,
child: Text('Hola'),
)

// Sin hijo (solo decoración)
Container(
width: 50,
height: 50,
color: Colors.red,
)

Explicación: Container puede tener o no un hijo. Es como una caja que puedes decorar, dimensionar y posicionar.

Center

Centra su hijo en el espacio disponible.

dart
Center(
child: Text('Texto Centrado'),
)

Explicación: Center toma su hijo y lo coloca exactamente en el centro del espacio disponible.

Padding

Añade espacio interno alrededor de su hijo.

dart
Padding(
padding: EdgeInsets.all(16),
child: Text('Texto con padding'),
)

// Padding específico
Padding(
padding: EdgeInsets.only(left: 20, top: 10),
child: Icon(Icons.star),
)

Explicación: Padding crea espacio interno entre los bordes del widget y su contenido hijo.

Widgets con Múltiples Hijos

Estos widgets pueden contener varios widgets hijos.

Column

Organiza hijos verticalmente.

dart
Column(
children: [
  Text('Elemento 1'),
  Text('Elemento 2'),
  Icon(Icons.star),
],
)

Explicación: Column apila sus hijos uno debajo del otro, como una lista vertical.

Row

Organiza hijos horizontalmente.

dart
Row(
children: [
  Icon(Icons.home),
  Text('Inicio'),
  Icon(Icons.arrow_forward),
],
)

Explicación: Row coloca sus hijos uno al lado del otro, como una fila horizontal.

ListView

Lista desplazable de elementos.

dart
ListView(
children: [
  ListTile(title: Text('Opción 1')),
  ListTile(title: Text('Opción 2')),
  ListTile(title: Text('Opción 3')),
],
)

Explicación: ListView crea una lista que se puede desplazar cuando el contenido es más grande que la pantalla.

Stack

Apila widgets unos sobre otros.

dart
Stack(
children: [
  Container(
    width: 100,
    height: 100,
    color: Colors.red,
  ),
  Positioned(
    top: 20,
    left: 20,
    child: Text('Encima'),
  ),
],
)

Explicación: Stack permite superponer widgets, como capas en un diseño gráfico.

Wrap

Organiza hijos y los envuelve a la siguiente línea.

dart
Wrap(
spacing: 8,
children: [
  Chip(label: Text('Tag 1')),
  Chip(label: Text('Tag 2')),
  Chip(label: Text('Tag 3')),
  Chip(label: Text('Tag 4')),
],
)

Explicación: Wrap es como Row pero cuando no hay espacio, mueve los elementos a la siguiente línea.

Ejemplo Práctico Completo

dart
class EjemploWidgets extends StatelessWidget {

Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('Widgets Demo')),
    body: Column(
      children: [
        // Widget sin hijo
        SizedBox(height: 20),
        
        // Widget con un hijo
        Container(
          padding: EdgeInsets.all(16),
          color: Colors.blue[100],
          child: Text('Container con padding'),
        ),
        
        // Separador sin hijo
        Divider(),
        
        // Widget con múltiples hijos
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Icon(Icons.star, color: Colors.yellow),
            Text('Rating'),
            Icon(Icons.favorite, color: Colors.red),
          ],
        ),
        
        // Espaciador flexible
        Spacer(),
        
        // Indicador sin hijo
        CircularProgressIndicator(),
        
        SizedBox(height: 20),
      ],
    ),
  );
}
}
  Nota

Tip: Los widgets sin hijos son perfectos para espaciado y elementos visuales simples. Los widgets con hijos te permiten crear layouts complejos combinándolos.

  Nota

Recuerda: Column y Row son los widgets de layout más usados. Container es el más versátil para diseño y decoración.

Cuándo Usar Cada Tipo


  Widgets Sin Hijos

  • Espaciado: SizedBox, Spacer
  • Separación visual: Divider, VerticalDivider
  • Indicadores: CircularProgressIndicator, LinearProgressIndicator
  • Elementos simples: Icon, Text

  Widgets Con Hijos

  • Layout vertical: Column
  • Layout horizontal: Row
  • Listas: ListView
  • Superposición: Stack
  • Contenedor: Container
  • Envolvimiento: Wrap

La clave está en entender que los widgets sin hijos son elementos terminales, mientras que los widgets con hijos son contenedores que organizan otros widgets.