flutter create my_app
Crear proyecto Flutter nuevo
flutter run
Ejecutar app en dispositivo conectado
flutter build apk --release
Compilar APK release
flutter build ios --release
Compilar iOS release
flutter pub add package_name
Añadir dependencia
flutter pub get
Instalar dependencias
flutter doctor
Comprobar instalación de Flutter
flutter clean
Limpiar artefactos de build
Text('Hello', style: TextStyle(fontSize: 20)) Widget de texto
Icon(Icons.star, color: Colors.amber)
Widget de icono
Image.asset('assets/logo.png') Cargar imagen local
Image.network('https://...') Cargar imagen remota
ElevatedButton(onPressed: () {}, child: Text('Go')) Botón Material elevado
TextButton(onPressed: () {}, child: Text('Go')) Botón de texto plano
IconButton(icon: Icon(Icons.add), onPressed: () {}) Botón con icono
TextField(decoration: InputDecoration(labelText: 'Name'))
Campo de texto
Switch(value: on, onChanged: (v) {}) Switch (interruptor)
Checkbox(value: checked, onChanged: (v) {}) Checkbox
CircularProgressIndicator()
Spinner de carga
Container(padding: EdgeInsets.all(16), color: Colors.blue)
Caja con padding y color
Padding(padding: EdgeInsets.all(8), child: ...)
Envolver con padding
Center(child: ...)
Centrar un hijo
Column(children: [w1, w2, w3])
Apilar verticalmente
Row(children: [w1, w2, w3])
Apilar horizontalmente
Stack(children: [bg, overlay])
Hijos superpuestos (eje Z)
Expanded(flex: 2, child: ...)
Rellenar espacio disponible en Row/Column
SizedBox(height: 16, width: 200)
Caja/espaciador de tamaño fijo
Wrap(children: [...])
Saltar de línea al llenarse
SingleChildScrollView(child: Column(...))
Hacer scrollable el contenido
ListView.builder(itemCount: n, itemBuilder: (c, i) => ...)
Lista con scroll (lazy)
GridView.count(crossAxisCount: 2, children: [...])
Grid con columnas fijas
class MyWidget extends StatelessWidget {
Widget build(BuildContext c) => ...;
} Widget stateless
class MyWidget extends StatefulWidget {
State<MyWidget> createState() => _S();
} Widget stateful
setState(() { count++; }); Disparar reconstrucción
@override
void initState() { super.initState(); } Hook de init (ciclo de vida)
@override
void dispose() { ...; super.dispose(); } Hook de cleanup (ciclo de vida)
final _controller = TextEditingController();
Controller del campo de texto
ValueNotifier<int>(0) + ValueListenableBuilder
Estado reactivo simple
FutureBuilder(future: fetch(), builder: (c, snap) => ...)
Widget de datos async
StreamBuilder(stream: s, builder: (c, snap) => ...)
Widget de datos Stream
Navigator.push(context, MaterialPageRoute(builder: (c) => NextPage()))
Push de nueva ruta
Navigator.pop(context)
Volver
Navigator.pushNamed(context, '/details')
Push de ruta nombrada
Navigator.pushReplacement(context, ...)
Reemplazar ruta actual
final result = await Navigator.push(...);
Push y esperar resultado
Navigator.pop(context, value);
Devolver valor al hacer pop
EdgeInsets.symmetric(horizontal: 16, vertical: 8)
Abreviatura de padding
BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8))
Caja con bordes redondeados
Theme.of(context).textTheme.headlineLarge
Acceder al theme
MediaQuery.of(context).size.width
Dimensiones de pantalla
MaterialApp(theme: ThemeData(primarySwatch: Colors.blue))
App con tema Material
Cheat Sheet de Flutter — Widgets, State Management, Navegación y Layout
Flutter llegó en 2017 con un único árbol de widgets inmutables reconstruido en cada cambio de estado, y ese modelo desconcierta a quien viene de UI imperativa. La chuleta de abajo cubre 50+ widgets y patrones en configuración, widgets, layout, estado, navegación y estilos. La mayoría de los líos en código Flutter no vienen de olvidar widgets. Vienen de rarezas que parecen normales hasta que muerden. Una llamada a `setState` reconstruye el subárbol de `State` entero desde ese widget hacia abajo, así que colocar el estado alto en el árbol convierte una interacción pequeña en un repaint de página y hunde los frame times. `Expanded` y `Flexible` lanzan en runtime fuera de un padre `Row`, `Column` o `Flex` — error frecuente al refactorizar un layout dentro de un `Stack` o un `Wrap`. Los controllers (`TextEditingController`, `ScrollController`, `AnimationController`) necesitan un `dispose` en el ciclo de vida del `State`, y olvidarlo deja listeners disparando contra widgets ya desmontados, que acaban lanzando una excepción. Estos son los fragmentos consultados al depurar eso: el widget de layout, el hook de ciclo de vida, la llamada de navigator que toca, sin releer el catálogo desde la primera entrada.
Trampas habituales en Flutter
Hay un puñado de patrones que merecen sitio cerca de la cabecera de cualquier pantalla Flutter. Conviene empujar el estado lo más abajo posible en el árbol; un `ValueListenableBuilder` alrededor de la hoja que se reconstruye sale mucho más barato que un `setState` sobre la página entera. Conviene marcar los constructores de widget como `const` siempre que se pueda, porque un widget `const` es igual por identidad entre rebuilds y Flutter se salta la reconstrucción — la mayor ganancia de rendimiento gratis en casi cualquier app. `BuildContext` está atado a una posición del árbol, así que llamar a `Navigator.of(context)` tras un `await` puede operar sobre un contexto cuyo widget ya fue eliminado — la comprobación `mounted` en el `State` existe para este caso. `MediaQuery.of(context).size` provoca un rebuild en cada apertura de teclado, rotación o cambio de escala de texto — útil cuando se busca, caro cuando es accidental. `ListView` construye todos los hijos de golpe, mientras que `ListView.builder` es perezoso, así que las listas largas deberían usar la forma builder. La chuleta agrupa esto en Setup, Widgets, Layout, Estado, Navegación y Estilos para que la sección adecuada esté a un clic.
- Más de 50 widgets y patrones Flutter
- Comandos CLI de configuración
- Widgets de layout (Column, Row, Stack)
- Ciclo de vida del estado y builders
- Navigator y rutas nombradas
- Copia al portapapeles con un clic
Gratis. Sin registro. Tus datos permanecen en tu navegador. Anuncios mediante Google AdSense (con consentimiento).
Por Marco B. ·