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.
Los widgets sin hijos son elementos independientes que no necesitan contener otros widgets para funcionar.
Este widget crea un espacio de tamaño fijo.
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.
Crea un espacio flexible que se expande.
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.
Muestra una línea horizontal de separación.
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.
Línea vertical de separación.
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.
Indicador de carga circular.
CircularProgressIndicator()
// Con color personalizado
CircularProgressIndicator(
color: Colors.blue,
strokeWidth: 6,
) Explicación: Muestra una rueda de carga giratoria, perfecta para indicar procesos en curso.
Barra de progreso horizontal.
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.
A continuación, se presentan algunos widgets con un hijo. Estos widgets pueden contener exactamente un widget hijo.
El widget más versátil para diseño.
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.
Centra su hijo en el espacio disponible.
Center(
child: Text('Texto Centrado'),
) Explicación: Center toma su hijo y lo coloca exactamente en el centro del espacio disponible.
Añade espacio interno alrededor de su hijo.
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.
Estos widgets pueden contener varios widgets hijos.
Organiza hijos verticalmente.
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.
Organiza hijos horizontalmente.
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.
Lista desplazable de elementos.
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.
Apila widgets unos sobre otros.
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.
Organiza hijos y los envuelve a la siguiente línea.
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.
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),
],
),
);
}
} Tip: Los widgets sin hijos son perfectos para espaciado y elementos visuales simples. Los widgets con hijos te permiten crear layouts complejos combinándolos.
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.
SizedBox, SpacerDivider, VerticalDividerCircularProgressIndicator, LinearProgressIndicatorIcon, TextColumnRowListViewStackContainerWrapLa clave está en entender que los widgets sin hijos son elementos terminales, mientras que los widgets con hijos son contenedores que organizan otros widgets.