Tema escuro no Flutter usando o GetX
Published: 2021-11-29 21:02:42

Criar um tema Claro e Escuro para o seu aplicativo se torna uma coisa obrigatória no mundo dos aplicativos de hoje. 

Porque a maioria das pessoas prefere um tema escuro em vez de um tema claro, porque é bastante confortável para os nossos olhos e reduz o consumo da bateria.

Para implementar um tema dinâmico, usaremos uma estrutura de flutter bem conhecida chamada GetX.

A maneira mais simples de mudar de claro para escuro é mudar o tema do widget MaterialApp para claro e para escuro. Para isso, precisamos de dois temas como escuro e claro.

Você não sabe o que é GetX? Eu escrevi um artigo que dá uma boa visão, dá uma olhada aqui: https://dev.to/riquez/por-que-o-getx-e-um-otimo-gerenciador-de-estado-no-flutter-3gc1

####Configurações iniciais para nosso app!

Defina os dados do tema claro e escuro (como a cor de destaque, cor primária e secundária, etc.)

```
ThemeData _darkTheme = ThemeData(
    accentColor: Colors.red,
    brightness: Brightness.dark,
    primaryColor: Colors.amber,
    buttonTheme: ButtonThemeData(
      buttonColor: Colors.amber,
      disabledColor: Colors.grey,
    ));
ThemeData _lightTheme = ThemeData(
    accentColor: Colors.pink,
    brightness: Brightness.light,
    primaryColor: Colors.blue,
    buttonTheme: ButtonThemeData(
      buttonColor: Colors.blue,
      disabledColor: Colors.grey,
    ))
```

Agora você deve adicionar uma variável para o usuário selecionar o tema.

Vamos adicionar a `RxBool _isLightTheme = false.obs`, pode ser dentro de uma controller, melhor.

Agora adicione isso dentro do seu GetMaterialApp!

```
theme: _lightTheme,
darkTheme: _darkTheme,
themeMode: ThemeMode.system,
```


![switch between](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gcr6wem8q7b3y5qbjvxv.gif)

Agora um exemplo de um Switch para o usuário poder selecionar

```
ObxValue(
  (data) => Switch(
     value: _isLightTheme.value,
     onChanged: (val) {
       _isLightTheme.value = val;
       Get.changeThemeMode(
          _isLightTheme.value ? ThemeMode.light : ThemeMode.dark,
        );
        _saveThemeStatus();
      },
    ),
    false.obs,
 ),
```

###Quer transformar ele em persistente?

Se sim, vamos fazer isso... As etapas a seguir irão ajudá-lo a manter o tema selecionado de forma persistente.

Em primeiro lugar, crie uma instância ou preferência compartilhada e adicione dois métodos para obter o valor do tema e definir o valor do tema.

```
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  _saveThemeStatus() async {
    SharedPreferences pref = await _prefs;
    pref.setBool('theme', _isLightTheme.value);
  }

  _getThemeStatus() async {
    var _isLight = _prefs.then((SharedPreferences prefs) {
      return prefs.getBool('theme') != null ? prefs.getBool('theme') : true;
    }).obs;
    _isLightTheme.value = await _isLight.value;
    Get.changeThemeMode(_isLightTheme.value ? ThemeMode.light : ThemeMode.dark);
```

Agora, para inicializar o tema selecionado em seu aplicativo, chame o método getThemeStatus() no início de seu aplicativo usando o método initState(), também é possível modificar e usar o onInit().

```
@override
  void initState() {
    super.initState();
    _getThemeStatus();
  }
```

Agora aqui vai o arquivo main.dart completo com tudo!

```
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

ThemeData _darkTheme = ThemeData(
    accentColor: Colors.red,
    brightness: Brightness.dark,
    primaryColor: Colors.amber,
    buttonTheme: ButtonThemeData(
      buttonColor: Colors.amber,
      disabledColor: Colors.grey,
    ));

ThemeData _lightTheme = ThemeData(
    accentColor: Colors.pink,
    brightness: Brightness.light,
    primaryColor: Colors.blue,
    buttonTheme: ButtonThemeData(
      buttonColor: Colors.blue,
      disabledColor: Colors.grey,
    ));

class MyApp extends StatelessWidget {
  RxBool _isLightTheme = false.obs;

  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  _saveThemeStatus() async {
    SharedPreferences pref = await _prefs;
    pref.setBool('theme', _isLightTheme.value);
  }

  _getThemeStatus() async {
    var _isLight = _prefs.then((SharedPreferences prefs) {
      return prefs.getBool('theme') != null ? prefs.getBool('theme') : true;
    }).obs;
    _isLightTheme.value = await _isLight.value;
    Get.changeThemeMode(_isLightTheme.value ? ThemeMode.light : ThemeMode.dark);
  }

  MyApp() {
    _getThemeStatus();
  }

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      theme: _lightTheme,
      darkTheme: _darkTheme,
      themeMode: ThemeMode.system,
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dark Mode Demo'),
        ),
        body: Container(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Obx(
                  () => Text(
                    'Click on switch to change to ${_isLightTheme.value ? 'Dark' : 'Light'} theme',
                  ),
                ),
                ObxValue(
                  (data) => Switch(
                    value: _isLightTheme.value,
                    onChanged: (val) {
                      _isLightTheme.value = val;
                      Get.changeThemeMode(
                        _isLightTheme.value ? ThemeMode.light : ThemeMode.dark,
                      );
                      _saveThemeStatus();
                    },
                  ),
                  false.obs,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
```

###Conclusão!

Há muitas maneiras de implementar temas dinâmicos no flutter, já que GetX é a maneira mais eficiente de implementá-los, resolvi demonstrar um exemplo. 

Espero que você tenha gostado deste conteúdo. Se você achou útil, compartilhe-o com sua equipe de desenvolvimento.

Obrigado por ler este artigo ❤

Referências: 

[GetX Package](https://pub.dev/packages/get)
[Shared Preferences Package](https://pub.dev/packages/shared_preferences)