Inicio Dart Alterna entre Modo Oscuro y Claro en Flutter

Alterna entre Modo Oscuro y Claro en Flutter

por Alberto Guaman
Este código en Flutter permite cambiar entre un tema claro y oscuro, y guardar la preferencia del usuario usando Provider para la gestión de estado y SharedPreferences para el almacenamiento persistente. Aquí te explico cada parte del código paso a paso.

Importaciones

				
					import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:provider/provider.dart';

				
			

Estas importaciones traen las bibliotecas necesarias:

  • flutter/material.dart: Proporciona el conjunto de widgets y temas de Material Design.
  • shared_preferences: Permite guardar datos pequeños (como las preferencias del usuario) en el dispositivo.
  • provider: Facilita la gestión de estado en Flutter.

Clase ThemeProvider

				
					class ThemeProvider with ChangeNotifier {
  ThemeMode _themeMode = ThemeMode.system;

  ThemeProvider() {
    _loadThemeMode();
  }

  ThemeMode get themeMode => _themeMode;

  void _loadThemeMode() async {
    final prefs = await SharedPreferences.getInstance();
    _themeMode = ThemeMode.values.firstWhere(
      (e) => e.toString() == prefs.getString('themeMode'),
      orElse: () => ThemeMode.system,
    );
    notifyListeners();
  }

  void setThemeMode(ThemeMode mode) async {
    _themeMode = mode;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('themeMode', mode.toString());
    notifyListeners();
  }

  bool get isDarkMode => _themeMode == ThemeMode.dark;
}

				
			
  1. ThemeMode _themeMode = ThemeMode.system;: Define el modo de tema actual. El valor por defecto es ThemeMode.system, que sigue la configuración del sistema operativo (oscuro o claro).
  2. ThemeProvider(): El constructor de la clase. Al instanciarse, llama a _loadThemeMode() para cargar el modo de tema guardado anteriormente.
  3. _loadThemeMode(): Esta función es asincrónica y se ejecuta al crear ThemeProvider. Accede a SharedPreferences para obtener el modo de tema guardado. Si no encuentra ninguna preferencia guardada, mantiene ThemeMode.system.
  4. setThemeMode(ThemeMode mode): Cambia el modo de tema según la preferencia del usuario y guarda esta preferencia en SharedPreferences. Luego, notifica a los oyentes (notifyListeners()), lo que desencadena la actualización de la interfaz.
  5. isDarkMode: Devuelve true si el tema actual es oscuro (ThemeMode.dark).
				
					void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => ThemeProvider(),
      child: MyApp(),
    ),
  );
}

				
			
  • ChangeNotifierProvider: Proporciona una instancia de ThemeProvider a toda la aplicación. ChangeNotifierProvider es un tipo de Provider que escucha cambios en un ChangeNotifier y notifica a los widgets que dependen de él.

  • MyApp: Es el widget principal de la aplicación.

Clase MyApp

				
					class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);

    return MaterialApp(
      title: 'Flutter Theme Demo',
      themeMode: themeProvider.themeMode,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      home: HomeScreen(),
    );
  }
}

				
			
  • Provider.of<ThemeProvider>(context): Obtiene la instancia de ThemeProvider creada anteriormente para acceder al modo de tema actual.

  • MaterialApp: Configura la aplicación con los temas light y dark, y establece themeMode según la preferencia del usuario.

Clase HomeScreen

				
					class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);

    return Scaffold(
      appBar: AppBar(title: const Text('Theme Switcher')),
      body: Center(
        child: SwitchListTile(
          title: const Text('Dark Mode'),
          value: themeProvider.isDarkMode,
          onChanged: (value) => themeProvider.setThemeMode(
            value ? ThemeMode.dark : ThemeMode.light,
          ),
        ),
      ),
    );
  }
}

				
			
  • SwitchListTile: Un widget que permite al usuario alternar entre el modo oscuro y claro. El interruptor refleja la preferencia del tema actual (value: themeProvider.isDarkMode).

  • onChanged: Se ejecuta cuando el usuario cambia el interruptor. Llama a setThemeMode para actualizar el tema y guardar la preferencia.

Conclusión

Este código crea una aplicación Flutter donde el usuario puede cambiar entre un tema oscuro y uno claro. La elección se guarda utilizando SharedPreferences, lo que garantiza que la preferencia se mantenga incluso si el usuario cierra y vuelve a abrir la aplicación. Provider se utiliza para gestionar el estado del tema y actualizar la interfaz de usuario cuando se cambia el tema.

Visita mi sitio web Para acceder a mi GITHUB: albertoguaman.com

Entradas relacionadas