Modo oscuro y claro en Flutter utilizando GetX
Tags: flutter, mobile, getx, dart
Published: 2023-10-11 14:43:12

En la actualidad, la implementación del modo oscuro y modo claro se ha convertido en una característica común en muchas aplicaciones. Implementar esta funcionalidad en una aplicación puede ser beneficioso para los usuarios, ya que les brinda la opción de elegir el tema que mejor se adapte a sus preferencias y necesidades. El modo oscuro, por ejemplo, puede ser útil para reducir la fatiga visual en entornos de poca luz, mientras que el modo claro puede ser más adecuado para entornos bien iluminados. No obstante, es importante tener en cuenta la accesibilidad y legibilidad en ambos modos para garantizar una experiencia óptima para todos los usuarios.

En este artículo vamos a explorar cómo implementar el modo oscuro y el modo claro en una aplicación utilizando el paquete [GetX](https://pub.dev/packages/get) en Flutter. GetX es un paquete de administración de estado y navegación que proporciona herramientas y funcionalidades útiles para el desarrollo de aplicaciones en Flutter.

## Creando nuestro proyecto

Para crear el proyecto ejecuta el siguiente comando.
```
flutter create getx_theme
```

Luego agregamos el paquete de GetX al proyecto en nuestro archivo `pubspec.yaml`.
```
get: any
```
Y por último ejecutamos el comando `pub get` para obtener los paquetes en nuestro proyecto.

```
flutter pub get
```

## Creando nuestro tema

Primero crearemos nuestro archivo `theme.dart` donde tendremos definidos nuestro modo claro y oscuro.

```
import 'package:flutter/material.dart';

final ThemeData darkAppTheme = ThemeData(
  brightness: Brightness.dark,
  primaryColor: Colors.amber,
  buttonTheme: const ButtonThemeData(
    buttonColor: Colors.amber,
    disabledColor: Colors.grey,
  ),
);

final ThemeData appTheme = ThemeData(
  brightness: Brightness.light,
  primaryColor: Colors.blue,
  buttonTheme: const ButtonThemeData(
    buttonColor: Colors.blue,
    disabledColor: Colors.grey,
  ),
);

```
Ahora, utilizando GetX crearemos un controlador para el manejo de nuestro tema dentro de la aplicación. Creamos el archivo `theme_controller.dart` y agregamos el siguiente código.

```
import 'package:get/get.dart';
import 'package:flutter/material.dart';

class ThemeController extends GetxController {
  ThemeController({required this.context});

  BuildContext context;
  late bool isDarkMode;

  @override
  void onInit() {
    isDarkMode = Theme.of(context).brightness == Brightness.dark;
    super.onInit();
  }

  void toggleDarkMode() {
    isDarkMode = !isDarkMode;
    if (isDarkMode) {
      Get.changeTheme(ThemeData.dark());
    } else {
      Get.changeTheme(ThemeData.light());
    }
    update();
  }
}
```

## Utilizando nuestro tema
Para utilizar nuestro tema crearemos una pantalla que será nuestro Home donde agregaremos un `action` en nuestro `AppBar` para establecer el tema de la aplicación.

Además en nuestro Home es donde utilizaremos el controlador creado para el manejo del valor actual de nuestro tema dentro de la aplicación:

```
Get.put(ThemeController(context: context));
```
Nuestro Home quedará de la siguiente manera:

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

  @override
  Widget build(BuildContext context) {
    Get.put(ThemeController(context: context));
    return Scaffold(
      appBar: AppBar(
        title: const Text('GetX Theme'),
        actions: [
          GetBuilder<ThemeController>(
            builder: (controller) => IconButton(
                icon: Icon(
                  controller.isDarkMode ? Icons.light_mode : Icons.dark_mode,
                ),
                onPressed: () => controller.toggleDarkMode()),
          ),
        ],
      ),
    );
  }
}
```

Finalmente en nuestro archivo `main.dart` utilizaremos `GetMaterialApp` de GetX para crear nuestro Widget principal. Adicionalmente estableceremos los valores para `theme` y `darkTheme` utilizando las configuraciones de los temas que agregamos en nuestro archivo `theme.dart`

```
void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      theme: appTheme,
      darkTheme: darkAppTheme,
      themeMode: ThemeMode.system,
      debugShowCheckedModeBanner: false,
      home: const HomeScreen(),
    );
  }
}
```

## Ejecutando nuestra aplicación
Utiliza el siguiente comando para correr la aplicación y puedas ver todo nuestro código en acción.

```
flutter run
```

## Conclusiones

En resumen, la implementación del modo oscuro y modo claro en una aplicación puede mejorar la experiencia del usuario al brindarles opciones de personalización y adaptabilidad. Existen diferentes manera de implementar esta funcionalidad y GetX es una de ellas, proporcionándonos una forma robusta y sencilla. 

Puedes revisar el código en [GitHub](https://github.com/rubone/getx_theme)

Happy Coding! :v: