DEV Community

Cover image for Tema escuro no Flutter usando o GetX
Henrique Pomatti dos Santos
Henrique Pomatti dos Santos

Posted on

Tema escuro no Flutter usando o GetX

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,
    ))
Enter fullscreen mode Exit fullscreen mode

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,
Enter fullscreen mode Exit fullscreen mode

switch between

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,
 ),
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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();
  }
Enter fullscreen mode Exit fullscreen mode

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,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Shared Preferences Package

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more