Flutter es un framework para crear interfaces multiplataforma a partir de widgets.
Si has llegado hasta aquí, ya conoces Dart. Ahora vamos a usar ese lenguaje para hablar con Flutter.
Flutter no es un lenguaje, es un UI Toolkit (un kit de herramientas de interfaz). Imagínalo como una caja gigante de piezas de Lego. Dart es la física que permite que esas piezas encajen, y Flutter son las piezas en sí (botones, textos, menús).
En esta entrada vamos a crear nuestro primer proyecto, entenderemos qué hay dentro de todas esas carpetas que se generan y escribiremos nuestra primera interfaz gráfica.
Creando el proyecto
Abre tu terminal (o la paleta de comandos de VS Code) y navega a donde guardes tus proyectos. Ejecuta:
flutter create mi_primera_app
Cuando termine, abre esa carpeta en VS Code. Verás un montón de archivos. No entres en pánico. Vamos a ver qué es lo importante y qué es “ruido”.
Anatomía de un proyecto Flutter
La estructura de carpetas de Flutter es muy opinada. Aquí tienes el mapa de carreteras:
La carpeta lib
Aquí vas a pasar casi todo el tiempo.
- Contiene todo tu código Dart (
.dart). - Al crear el proyecto, verás un archivo
main.dart. Ese es el punto de entrada de tu aplicación.
El archivo pubspec.yaml
Es el archivo más importante de configuración. Escrito en YAML (un formato muy sensible a la indentación), define:
- Metadatos: Nombre de la app, versión y descripción.
- Dependencias: Librerías de terceros que usaremos (como Google Maps, o un selector de fechas).
- Assets: Aquí registramos las imágenes y fuentes tipográficas locales.
Cuidado con los espacios: En YAML, la indentación es estricta. Dos espacios mal puestos y el archivo dará error. Usa siempre 2 espacios por nivel.
Las carpetas de cada plataforma
Flutter genera carpetas con los proyectos y la configuración de cada plataforma, como android, ios, web, windows, macos y linux, según las plataformas habilitadas.
- Generalmente no se tocan, a menos que necesites configurar permisos específicos (como usar la cámara o el GPS) o cambiar el icono de la App.
La carpeta build
Se genera automáticamente y contiene los ejecutables compilados. Nunca escribas nada aquí, porque se borra cada vez que compilas.
Todo es un widget
Antes de escribir código, grábate esto a fuego: En Flutter, TODO es un Widget.
- ¿Un botón? Es un Widget.
- ¿Un texto? Es un Widget.
- ¿El espacio entre dos elementos? Es un Widget (
SizedBox). - ¿La alineación al centro? Es un Widget (
Center). - ¿La aplicación entera? Es un Widget.
La interfaz se construye creando un Árbol de Widgets (Widget Tree), donde unos widgets contienen a otros.
Limpiando main.dart
Por defecto, Flutter trae una app de “Contador” de ejemplo. Es genial, pero tiene demasiado ruido para empezar.
Vamos a borrar todo el contenido de lib/main.dart y escribirlo desde cero.
Importar Material
Lo primero es traer la caja de herramientas de diseño de Google (Material Design).
import 'package:flutter/material.dart';
La función main
Igual que vimos en Dart, necesitamos un punto de entrada. Pero ahora, en lugar de hacer un print, vamos a “arrancar” la interfaz con la función runApp().
void main() {
runApp(MiPrimeraApp());
}
El widget raíz MaterialApp
Aquí definimos nuestra clase MiPrimeraApp. Como nuestra App no va a cambiar (de momento), será un StatelessWidget (Widget sin estado).
El widget más importante que vamos a devolver aquí es MaterialApp.
MaterialApp es el “envoltorio” principal. Nos proporciona:
- Navegación entre páginas.
- Temas (colores, fuentes).
- La configuración básica para que la App se vea bien en Android y iOS.
class MiPrimeraApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Hola Flutter',
home: Text('Hola Mundo'), // Esto se verá feo, sigue leyendo
);
}
}
Si ejecutas esto, verás un texto “Hola Mundo” en la esquina superior izquierda, con fondo negro y subrayado rojo feo. ¿Por qué? Porque MaterialApp configura la App, pero no “pinta” el lienzo blanco típico de una pantalla. Para eso necesitamos un Scaffold.
Scaffold: el andamio de la pantalla
El Scaffold es el widget que implementa la estructura visual básica de Material Design. Nos da automáticamente:
- Un AppBar (barra superior).
- Un Body (el cuerpo de la app).
- Un FloatingActionButton (botón flotante).
- Un Drawer (menú lateral).
Vamos a mejorar nuestro código usando un Scaffold dentro del home de MaterialApp.
import 'package:flutter/material.dart';
void main() => runApp(MiPrimeraApp());
class MiPrimeraApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Quitamos la etiqueta de "Debug" de la esquina
debugShowCheckedModeBanner: false,
title: 'Mi App',
theme: ThemeData(primarySwatch: Colors.blue),
// Aquí empieza la pantalla principal
home: Scaffold(
appBar: AppBar(
title: Text('Bienvenido a Flutter'),
backgroundColor: Colors.blueAccent,
),
body: Center(
child: Text(
'Hola LuisLlamas.es',
style: TextStyle(fontSize: 24, color: Colors.black87),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print('Botón pulsado');
},
child: Icon(Icons.add),
),
),
);
}
}
El anidamiento de widgets
Fíjate en la estructura de árbol:
MaterialApp(Configuración Global)Scaffold(Estructura de Pantalla)Center(Layout para centrar)Text(Contenido final)
Al principio, ver tanto paréntesis ))); al final asusta. Pero con VS Code y la extensión de Flutter, verás guías de colores que te ayudan a saber dónde cierra cada cosa.
Ejecutando la aplicación
Para ver tu creación:
- Abre un simulador (Android/iOS) o conecta tu móvil por USB.
- Pulsa
F5en VS Code.
¡Felicidades! Acabas de renderizar tu primera interfaz nativa a 60fps.