Ir al contenido

Guía de Flutter para novatos - Miguel Páramos

FAQ sobre Flutter pal que no tiene ni idea de Flutter | 2º DAM · PMDM

Ejemplo práctico de StatefulWidget: Pantalla interactiva que cambia de color y texto al pulsar un botón

Para comprender en detalle cómo opera la reactividad en Flutter con StatefulWidget, el siguiente ejemplo funcional implementa una pantalla interactiva que rota cíclicamente entre cuatro combinaciones de color de fondo y textos descriptivos cada vez que el usuario presiona un botón:

import 'package:flutter/material.dart'; // Importa el catálogo de diseño Material
class PantallaColores extends StatefulWidget { // Widget con estado interactivo propio
const PantallaColores({super.key}); // Constructor constante de la pantalla
@override // Sobreescribe la creación de estado
State<PantallaColores> createState() => _PantallaColoresState(); // Instancia el objeto de estado
} // Fin de la clase PantallaColores
class _PantallaColoresState extends State<PantallaColores> { // Objeto de estado mutable persistente
int _colorIndex = 0; // Índice numérico del color actualmente visible
final List<Map<String, dynamic>> _colores = [ // Colección de opciones temáticas
{ // Opción 0: Azul
'nombre': 'Azul Suave', // Nombre descriptivo
'color': const Color(0xFFBFDBFE), // Tono de fondo
'textoColor': const Color(0xFF1E3A8A), // Tono del texto para alto contraste
}, // Fin de opción 0
{ // Opción 1: Verde
'nombre': 'Verde Menta', // Nombre descriptivo
'color': const Color(0xFFBBF7D0), // Tono de fondo
'textoColor': const Color(0xFF065F46), // Tono del texto
}, // Fin de opción 1
{ // Opción 2: Ámbar
'nombre': 'Ámbar Cálido', // Nombre descriptivo
'color': const Color(0xFFFED7AA), // Tono de fondo
'textoColor': const Color(0xFF9A3412), // Tono del texto
}, // Fin de opción 2
{ // Opción 3: Lavanda
'nombre': 'Lavanda', // Nombre descriptivo
'color': const Color(0xFFE9D5FF), // Tono de fondo
'textoColor': const Color(0xFF581C87), // Tono del texto
}, // Fin de opción 3
]; // Fin de la lista de colores
void _rotarColor() { // Método de negocio que actualiza el estado
setState(() { // Notifica al framework que debe redibujar la vista
_colorIndex = (_colorIndex + 1) % _colores.length; // Avanza cíclicamente de 0 a 3
}); // Fin de setState
} // Fin de _rotarColor
@override // Sobreescribe el método build
Widget build(BuildContext context) { // Reconstruye la interfaz con los datos vigentes
final actual = _colores[_colorIndex]; // Extrae la configuración cromática activa
return Scaffold( // Andamio general de la pantalla
backgroundColor: actual['color'] as Color, // Aplica el color de fondo dinámico
appBar: AppBar( // Barra superior de navegación
title: const Text('Pantalla de Colores (StatefulWidget)'), // Título de la vista
), // Fin de AppBar
body: Center( // Centra el contenido en pantalla
child: Column( // Distribuye verticalmente los componentes
mainAxisAlignment: MainAxisAlignment.center, // Alineación vertical centrada
children: [ // Widgets hijos
Text( // Muestra el nombre del color seleccionado
'Color actual: ${actual['nombre']}', // Interpolación de texto con el dato dinámico
style: TextStyle( // Estilo tipográfico adaptado
fontSize: 22, // Tamaño de fuente en píxeles lógicos
fontWeight: FontWeight.bold, // Grosor negrita
color: actual['textoColor'] as Color, // Color de texto de contraste
), // Fin de TextStyle
), // Fin de Text
const SizedBox(height: 24), // Separación vertical de 24 píxeles
ElevatedButton.icon( // Botón con icono descriptivo
onPressed: _rotarColor, // Asocia el evento clic a la función mutadora
icon: const Icon(Icons.palette), // Icono de paleta de pintura
label: const Text('Cambiar Siguiente Color'), // Etiqueta del botón
), // Fin de ElevatedButton.icon
], // Fin de children
), // Fin de Column
), // Fin de Center
); // Fin de Scaffold
} // Fin del método build
} // Fin de la clase _PantallaColoresState
  • createState(): Es el método del StatefulWidget que crea la instancia del estado mutable asociado (_PantallaColoresState).
  • setState(() { ... }): Es la llamada obligatoria para modificar variables de estado. Modifica _colorIndex e inmediatamente marca el widget como “sucio” (dirty), programando una ejecución de build() en el siguiente fotograma del motor de renderizado.
  • Operador módulo % _colores.length: Al sumar 1, cuando el índice alcanza el valor 4, el resto de la división 4 % 4 es 0, haciendo que la rotación sea un bucle infinito seguro sin riesgo de desbordar la lista.