Flutter en el desarrollo móvil: qué es, conceptos clave y cómo funciona

Autor: IT Sectr Publicado: 2026-07-09 Tiempo de lectura: 11 min

Flutter es un framework de UI de Google para aplicaciones nativas multiplataforma. Según Flutter Docs (2025), Flutter se utiliza en más de 500 000 aplicaciones en Google Play. Comprender Widget, StatefulWidget, BuildContext y el árbol de renderizado es la base del desarrollo con Flutter.

Puntos clave

  • Widget — bloque de construcción básico. StatelessWidget (inmutable) vs StatefulWidget (mutable con setState()).
  • Tres árboles: Widget Tree (configuración), Element Tree (elementos), RenderObject Tree (renderizado).
  • BuildContext — acceso a InheritedWidget: Theme, MediaQuery, Navigator. InheritedWidget — paso de datos hacia abajo.
  • Navigator — pila de pantallas (Routes). Navigator 2.0 (Router) — navegación declarativa.
  • Hot Reload — inyección de cambios en 1-2 segundos. Conserva el estado. Hot Restart — reinicio completo.

Flutter: conceptos básicos de Widget, StatelessWidget y StatefulWidget

Widget — una descripción declarativa de una parte de la UI. Todo en Flutter es un Widget: desde un botón hasta la propia aplicación. Un Widget es configuración (no la UI en sí). StatelessWidget — un Widget inmutable. build() se llama una vez. No tiene estado. Se usa para contenido estático. StatefulWidget — un Widget mutable. Tiene un objeto State que puede cambiar. setState() — desencadena rebuild. State — un objeto mutable vinculado a un StatefulWidget. Contiene datos que pueden cambiar.

StatelessWidget vs StatefulWidget

StatelessWidget — build() se llama una vez. Adecuado para encabezados, iconos, textos estáticos. StatefulWidget — build() se llama cada vez que se invoca setState(). Adecuado para formularios, listas con cambios, temporizadores. InheritedWidget — paso de datos hacia abajo sin pasar explícitamente por constructores. Theme, MediaQuery, Navigator — InheritedWidgets. BuildContext — posición de un Widget en el árbol. context.of<T>, context.watch<T>, context.select<T,R> — acceso a InheritedWidget.

dart
// Ejemplo Flutter Widget: StatefulWidget con setState
class CounterWidget extends StatefulWidget {
  const CounterWidget({Key? key}) : super(key: key);

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter Counter')),
      body: const Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('You have pushed the button:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Widget — configuración. StatelessWidget — inmutable. StatefulWidget — mutable con setState(). IT Sectr recomienda empezar con StatelessWidget y cambiar a StatefulWidget solo cuando necesites estado.

Árboles (Widget Tree, Element Tree, RenderObject Tree)

Flutter usa tres árboles para un renderizado eficiente. Widget Tree — árbol de configuración. Los Widgets se crean con frecuencia (cada build), son ligeros. Element Tree — árbol de elementos. Un elemento por Widget (si el tipo no cambia). Element — puente entre Widget y RenderObject. RenderObject Tree — árbol de renderizado. Gestiona tamaños, posiciones, pintado. RenderObject — pesado, se crea raramente. Flutter compara el Widget Tree y actualiza el Element Tree, lo que desencadena la actualización del RenderObject Tree.

Keys y Element Tree

Key — identificador de Widget en el Element Tree. ValueKey, ObjectKey, UniqueKey, PageStorageKey. Las Keys permiten a Flutter emparejar Widgets viejos y nuevos durante el rebuild. Sin Keys, Flutter empareja por tipo de Widget y posición. GlobalKey — acceso a State desde otro Widget. Se usa para: formularios complejos, animaciones, acceso a State en tests. IT Sectr recomienda usar Keys para listas (List.generate) y evitar GlobalKey a menos que sea necesario.

Expanded — Widget que llena el espacio disponible en Row/Column/Flex. Flexible — no obliga a llenar (puede ser más pequeño). MediaQuery — InheritedWidget con información del dispositivo: tamaño de pantalla, orientación, plataforma, factor de escala de texto. Theme/ThemeData — tema centralizado. Theme.of(context) — acceso. MaterialApp — Widget raíz para configuración de enrutamiento, temas, locales. Scaffold — layout básico con AppBar, Drawer, BottomNavigationBar. AppBar — panel superior.

Navigator — pila de rutas (Routes). Navigator.push — abrir pantalla (devuelve Future). Navigator.pop — cerrar (con resultado). MaterialPageRoute — transición animada (slide desde la derecha). Named Routes — identificadores de cadena. onGenerateRoute — manejador centralizado. Navigator 2.0 (Router + RouteInformationParser + RouterDelegate) — navegación declarativa para web, deep linking y escenarios complejos.

Navigator 2.0 — navegación declarativa. Router — Widget central. RouteInformationParser — parseo de URL. RouterDelegate — gestión de la pila. GoRouter (paquete) — envoltorio simplificado sobre Navigator 2.0. Soporta: rutas nombradas, parámetros, redirect, deep linking. IT Sectr recomienda GoRouter para la mayoría de proyectos y Navigator 2.0 solo para escenarios complejos (web, desktop).

Asincronía (FutureBuilder, StreamBuilder)

FutureBuilder — Widget que construye UI basándose en un Future. connectionState: none, waiting, active, done. Se usa para: peticiones HTTP, lectura de BD, temporizadores. StreamBuilder — Widget para Stream (flujo infinito de datos). snapshot.data, snapshot.hasError, snapshot.hasData. Se usa para: WebSocket, Firebase, actualizaciones de ubicación. Ambos Widgets se reconstruyen al recibir nuevos datos.

State Management

Provider — DI simple + state management. ChangeNotifierProvider, MultiProvider. Riverpod — reemplazo moderno de Provider: seguro en compilación, independiente de BuildContext. Bloc — arquitectura Event-Driven: Cubit (eventos simples) vs Bloc (complejos). GetX — state management ligero + DI + routing. setState — el más simple, para estado local. IT Sectr recomienda Riverpod para proyectos nuevos y Provider para existentes.

Temas y adaptación (MediaQuery, ThemeData)

MediaQuery — tamaño de pantalla, orientación, plataforma, textScaleFactor. MediaQuery.of(context).size.width. ThemeData — tema de la app: colores, fuentes, formas. Theme.of(context).textTheme.bodyLarge. Hot Reload — inyección de código en una app en ejecución. Conserva el estado. No soporta: cambiar main(), variables globales, campos estáticos. Hot Restart — reinicio completo de la app (pérdida de estado). Hot Reload — principal ventaja de Flutter para desarrolladores.

Tipo de Widget Descripción Ejemplos
StatelessWidgetInmutable, build una vezText, Icon, Padding, Center
StatefulWidgetMutable, setState rebuildTextField, Checkbox, AnimationController
InheritedWidgetPaso de datos hacia abajoTheme, MediaQuery, Navigator
ProxyWidgetEnvoltorio para otros WidgetsParentDataWidget (Positioned, Expanded)
RenderObjectWidgetCrea RenderObjectColumn, Row, Stack (personalizados)

StatelessWidget — para contenido estático. StatefulWidget — para contenido dinámico. InheritedWidget — para DI. IT Sectr recomienda StatelessWidget por defecto y StatefulWidget solo cuando sea necesario.

Responsive Layout

LayoutBuilder — adaptación a las dimensiones del padre. OrientationBuilder — adaptación a la orientación. Expanded vs Flexible — distribución de espacio en Row/Column. MediaQuery — breakpoints para tablets y escritorios. SafeArea — márgenes de elementos del sistema (notch, status bar). AspectRatio — mantener proporciones. IT Sectr recomienda LayoutBuilder para layouts adaptativos y OrientationBuilder para orientación horizontal.

Testing (Widget, Integration, Unit)

Unit tests — prueba de lógica de negocio, repositorios, modelos. dart test — ejecución. Widget tests — prueba de widgets de forma aislada. WidgetTester — pumpWidget, tap, enterText. Integration tests — escenarios completos en un dispositivo/emulador real. Mockito — mockeo de dependencias. Golden tests — comparación de capturas de pantalla (golden files). IT Sectr recomienda Widget tests para cada pantalla y Unit tests para la lógica de negocio.

dart
void main() {
  testWidgets('Counter increments on tap', (tester) async {
    await tester.pumpWidget(const MaterialApp(home: CounterWidget()));

    expect(find.text('0'), findsOneWidget);

    await tester.tap(find.byType(FloatingActionButton));
    await tester.pump();

    expect(find.text('1'), findsOneWidget);
  });
}

Animaciones (Implícitas, Explícitas, Hero)

Animaciones implícitas — AnimatedContainer, AnimatedOpacity, AnimatedPadding, TweenAnimationBuilder. Los cambios de propiedad se animan automáticamente. Animaciones explícitas — AnimationController con Tween. forward() / reverse(). Animación Hero — Widget Hero con un tag — animación de transición entre pantallas. Animación escalonada — cadena de animaciones con Interval. Lottie — integración de animaciones de After Effects. Rive — animaciones interactivas (state machine). IT Sectr recomienda AnimatedContainer para el 80% de los casos y AnimationController para escenarios complejos.

dart
class AnimatedBox extends StatefulWidget {
  @override
  State<AnimatedBox> createState() => _AnimatedBoxState();
}

class _AnimatedBoxState extends State<AnimatedBox> {
  bool _expanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() => _expanded = !_expanded),
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeInOut,
        width: _expanded ? 200 : 100,
        height: _expanded ? 200 : 100,
        color: _expanded ? Colors.blue : Colors.red,
        child: const Center(child: Text('Tap me')),
      ),
    );
  }
}

Redes (http, dio, graphql)

http — cliente HTTP simple (get, post, put, delete). dio — cliente avanzado con interceptores, timeouts, reintentos, logging. graphql_flutter — cliente GraphQL para Flutter. json_serializable — generación de fromJson/toJson mediante anotaciones. Retrofit Dart — cliente HTTP type-safe como Retrofit. WebSocket — mediante web_socket_channel. Firebase — Cloud Firestore, Realtime Database, Cloud Functions. IT Sectr recomienda dio para REST API y graphql_flutter para GraphQL.

Flutter DevTools — conjunto de herramientas: Inspector (árbol de widgets), Timeline (rendimiento), Memory, Network, Logging. Profile mode — perfilado sin debug. Performance overlay — FPS, tiempos de build. Flame chart — gráfico de llama. DevTools — herramienta esencial para optimizar aplicaciones Flutter en producción.

Flutter Web — compilación de Flutter a WASM (WebAssembly). CanvasKit (Skia) vs HTML renderer. CanvasKit — pixel-perfect, pero más pesado. HTML renderer — ligero, pero con limitaciones. WASM (Flutter 3.22+) — rendimiento nativo. Adaptación responsive mediante LayoutBuilder y MediaQuery. IT Sectr recomienda CanvasKit para aplicaciones web de escritorio y HTML renderer para sitios de contenido.

Preguntas frecuentes

¿Cuál es la diferencia entre StatelessWidget y StatefulWidget?

StatelessWidget — inmutable, build una vez. StatefulWidget — con State mutable y setState().

¿Qué son Widget Tree, Element Tree y RenderObject Tree?

Widget Tree — configuración. Element Tree — puente. RenderObject Tree — renderizado (tamaños, pintado).

¿Qué son BuildContext e InheritedWidget?

BuildContext — posición del Widget en el árbol. InheritedWidget — paso de datos hacia abajo (Theme, MediaQuery).

¿Cómo funcionan Navigator y Route en Flutter?

Navigator — pila de pantallas. push() → pop(). Named Routes — nombres de cadena. Navigator 2.0 — declarativo.

¿Cómo funciona Hot Reload en Flutter?

Hot Reload — inyección de código en 1-2 segundos, conservación del estado. Hot Restart — reinicio completo.

Resumen

  • Widget — todo es un Widget. StatelessWidget vs StatefulWidget — dicotomía básica.
  • Tres árboles: Widget → Element → RenderObject. Widget — configuración, RenderObject — renderizado.
  • BuildContext + InheritedWidget — acceso a Theme, MediaQuery, Navigator sin paso explícito.
  • Navigator — pila de pantallas. Navigator 2.0 — navegación declarativa para web y deep links.
  • FutureBuilder — para Future. StreamBuilder — para Stream (Firebase, WebSocket).
  • MaterialApp + Scaffold — esqueleto de la app. ThemeData — tema centralizado.
  • Hot Reload — característica estrella de Flutter. Actualización de código en segundos con conservación del estado.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto