Alura > Cursos de Mobile > Cursos de Flutter > Conteúdos de Flutter > Primeiras aulas do curso Flutter: utilizando o Getx para gerenciamento de estados

Flutter: utilizando o Getx para gerenciamento de estados

Criando e manipulando observáveis - Apresentação

Olá! Meu nome é Matheus, sou instrutor aqui na Alura, e desejo boas-vindas a mais um curso de Flutter, este com foco em GetX.

Audiodescrição: Matheus Alberto se identifica como uma pessoa branca. Possui cabelos castanhos escuros e curtos. No corpo, usa uma camiseta preta. Ao fundo, um dos estúdios da Alura, com uma parede lisa iluminada em tons de roxo e amarelo, e no canto direito, uma estante com vários artefatos geek.

Conhecendo o projeto

O aplicativo que vamos desenvolver se chama Panucci Delivery. É um aplicativo de entrega, no qual as pessoas podem adicionar itens na sacola e terão feedback visual informando se o item foi adicionado ou removido dela.

As pessoas também podem navegar para o carrinho de compras, numa página de checkout, onde haverá um resumo do pedido, com todos os itens, e o total da compra. Assim que a pessoa fizer o pedido clicando em "Pedir", será e enviada de volta ao dashboard.

Isso será construído utilizando a biblioteca GetX.

Conhecendo o GetX

O GetX é uma ferramenta bastante extensa e completa que permite fazer injeção de dependências, gerenciamento de estados e interações de pessoa usuária, tudo em um único pacote.

Pré-requisitos

Para seguir este curso, é importante ter conhecimentos básicos de Flutter e de alguns gerenciadores de estados, como, por exemplo, o MobX.

Gostou do conteúdo? Acompanhe-nos nessa jornada!

Nos encontraremos no próximo vídeo!

Criando e manipulando observáveis - O que é uma observável

A empresa para a qual trabalhamos solicitou que desenvolvêssemos um aplicativo de delivery chamado Panucci Delivery.

No Figma, podemos ver o projeto que vamos desenvolver.

Duas telas do aplicativo Panucci Delivery, sobre fundo branco, retiradas do Figma. A primeira, à esquerda, uma tela de seleção de produtos com uma barra de pesquisa no topo, três listas intituladas 'Categoria' exibindo repetidas vezes o item 'Pão rapid10' por R$ 12,90, com opções de quantidade e botões de adição e remoção. Na parte inferior, uma barra vermelha com o texto 'Ver carrinho' no centro, um ícone de carrinho de compras à esquerda e o valor de R$ 50,00 à direita. A segunda tela, à direita, exibe o resumo do pedido com quatro itens listados como 'Nome produto' por R$ 12,90 cada. Abaixo, uma seção de pagamento mostrando um cartão Visa , seguida pela seção 'Confirmar', mostrando o valor total de R$ 170,28. Na parte inferior, um grande botão vermelho com o ícone de um saco de compras e o texto 'Pedir'.

Ele será desenvolvido em duas partes, das quais a primeira é a visual. Uma equipe, dentro da nossa, desenvolverá a parte visual, ou seja, os componentes e as telas. A segunda parte, na qual vamos trabalhar, é a interação dessas telas com a pessoa usuária.

Ao clicar no botão com o símbolo de "mais" para adicionar um item, esse item deve ser somado ao contador, adicionado à sacola de compras, e ter valor adicionado ao total calculado no carrinho.

Ao clicar em "Ver carrinho", levaremos a pessoa usuária para a outra página, de checkout, onde haverá um resumo de todos os itens colocados na sacola, o total da compra e o botão "Pedir".

Implementando a Interação da Pessoa usuária

Vamos para o editor de código — no caso do vídeo, o VS Code. A equipe já fez toda a parte visual para nós, e já temos acesso a tudo.

Olhando o emulador com a aplicação aberta, já temos todos os componentes montados e prontos. O que falta é a interação.

Se clicarmos no botão de "mais" para adicionar o item Chicken Salad, por exemplo, nada acontece. Isso porque não estamos observando ou gerenciando o estado do contador, onde há o valor zero, em busca de mudanças.

O mesmo ocorre no botão "Ver carrinho". Clicando nele, não somos levados para a página de checkout. Além disso, nem o total de compras, nem o valor total de itens dentro do carrinho são alterados.

Para fazer essa interação com a pessoa usuária, vamos utilizar o GetX. Vamos ver como será o processo de instalação do GetX.

Instalando o GetX

Existem duas formas de instalar o GetX na aplicação:

Vamos seguir a segunda opção. Acessaremos o arquivo pubspec.yaml, digitando nome na barra de busca no topo do VS Code e selecionando esse arquivo.

Em interior, dentro do bloco dependencies, abaixo do cupertino_icons, vamos adicionar get, dois pontos e passar a versão ^4.6.6. Recomendamos esse método para garantir que estamos utilizando a mesma versão mostrada no curso.

pubspec.yaml

dependencies:
    flutter:
        sdk: flutter


    # The following adds the Cupertino Icons font to your application.
    # Use with the CupertinoIcons class for iOS style icons.
    cupertino_icons: ^1.0.6
    get: ^4.6.6

Ao salvar o pubspec.yaml, o Visual Studio Code vai atualizar automaticamente os pacotes. Caso ele não faça isso, podemos abrir o terminal e rodar o comando abaixo para atualizar os pacotes instalados dentro do pubspec.yaml.

flutter pub get

Após baixados os pacotes, podemos começar a utilizar o GetX.

Utilizando o GetX

Podemos navegar para a pasta de componentes. Acessaremos o explorador na lateral esquerda do Visual Studio Code e navegaremos pelo caminho de pastas "lib > components", no qual acessaremos o arquivo cartao.dart.

O cartao.dart tem todas as informações relacionadas ao cartão. Próximo à linha 53, abaixo dos parênteses de um Inkwell, temos o valor do contador, que atualmente está fixo em zero.

cartao.dart

Inkwell(
    //Código omitido
)
Text("0"),
// Código omitido

Para usar o GetX, vamos criar um Observável (Observable, em inglês).

Não vamos entrar em detalhes sobre isso, porque consideramos que você já tem conhecimentos prévios de gerenciamento de estados. Para resumir, um Observável é uma variável observada em busca de mudanças. Ou seja, assim que o valor dessa variável é alterado, o Flutter é notificado para fazer alterações visuais na tela.

Antes de adicionar o observável, vamos acessar a linha da const Cartao, por volta da linha 6, e remover o const, porque agora estamos trabalhando com variáveis e o cartão não é mais uma constante.

class Cartao extends StatelessWidget {
    Cartao({Key? key, required this.item}) : super(key: key);
    final Item item;
    
    // Código omitido

Para fazer a criação dessa Observável dentro do cartão, vamos pular uma linha abaixo de final Item item, por volta da linha 7. Em seguida, vamos criar um var chamado counter (contador em inglês). Ele será igual a 0.obs, porque queremos que o valor iniciado seja zero.

class Cartao extends StatelessWidget {
    const Cartao({Key? key, required this.item}) : super(key: key);
    final Item item;
    
    var counter = 0.obs;
    
    // Código omitido

O obs apontará um erro, como esperado. Vamos posicionar o cursor em cima da palavra "obs", pressionar "Ctrl+." e verificar na lista de sugestões que há opções de importação.

É muito importante tomarmos cuidado com o tipo de importação que vamos adicionar. Existem vários pacotes, todos do get, mas só podemos usar dois: o state_manager.dart ou o get.dart.

Vamos selecionar o get.dart, porque é mais genérico. Isso gerará o código de importação abaixo, por volta da linha 2.

import 'package:get/get.dart';

Com isso, temos a Observável. Podemos Salvar o arquivo.

A seguir, veremos como trabalhar com essa Observável.

Criando e manipulando observáveis - Alterando observáveis

Nós criamos a Observável, mas ainda não estamos fazendo nada com ela. Ao acessar o emulador e clicar no botão de adicionar ou remover abaixo de um item, este não é adicionado nem removido. Nenhuma alteração está acontecendo.

Portanto, precisamos implementar a Observável dentro do contador do cartão.

Implementando a Observável

Vamos para o Visual Studio Code, no arquivo cartao.dart. Descendo até meados da linha 56, onde temos o Text do contador fixado em zero, vamos pedir para ele que, ao invés de utilizar um valor fixo, utilize o Observável.

Para isso, apagaremos o zero e adicionaremos o contador, que vai ser um counter.toString(), porque precisamos trabalhar com strings dentro do texto.

cartao.dart

Inkwell(
    //Código omitido
)
Text(counter.toString()),
// Código omitido

Vamos salvar o código do cartão e ver o que aconteceu dentro do emulador. Constataremos que nada ocorreu ainda.

Voltando ao Visual Studio Code, Na linha em que declaramos o var counter, vamos trocar o 0 da Observável por 1, só para ver se essa mudança está realmente acontecendo.

class Cartao extends StatelessWidget {
    const Cartao({Key? key, required this.item}) : super(key: key);
    final Item item;
    
    var counter = 1.obs;
    
    // Código omitido

Salvaremos o arquivo e voltaremos para o emulador.

Em seu interior, veremos que quantidade de todos os itens aumentou de 0 para 1. Isso significa que o contador está sendo reconhecido pelo Flutter, sendo mostrado e alterado na tela.

Para alterar esses valores, podemos utilizar funções simples de adicionar e remover um item. Voltando ao editor de código, acima do Text(counter.toString()), temos o Inkwell do botão de remover. Em seu interior, temos a da função onTap desse botão.

Nessa linha, vamos acessar o interior das chaves do onTap, pressionar "Enter" para descer uma linha e fazer uma função simples, counter--, para remover um número do contador.

Já no onTap do botão de adicionar, localizado no Inkwell abaixo do Text(counter.toString()), vamos colocar counter++ para adicionar um item ao contador.

InkWell(
    borderRadius: BorderRadius.circular(20),
    onTap: () {
        counter--;
    },
    child: const Icon(
        Icons.remove_circle_outline,
        size: 20,
    ),
),
Text(counter.toString()),
InkWell(
    borderRadius: BorderRadius.circular(20),
    onTap: () {
        counter++;
    },
    child: const Icon(
        Icons.add_circle_outline,
        size: 20,
    ),
),

Por fim, vamos voltar a var counter para o valor zero.

class Cartao extends StatelessWidget {
    const Cartao({Key? key, required this.item}) : super(key: key);
    final Item item;
    
    var counter = 0.obs;
    
    // Código omitido

Salvaremos o cartão, acessaremos o emulador e veremos que nada aconteceu ainda. Ao clicar nos botões de "mais" e de "menos", nada está acontecendo.

Nós estamos utilizando a Observável. Mas se lembrarmos de conceitos do Flutter, utilizamos a função setState para verificar ou modificar o Flutter de que o estado fica alterado.

Contudo, para a função setState funcionar, todo o Widget deveria ser um Stateful Widget, ao invés de um Stateless Widget.

Além disso, o GetX tem uma maneira diferente de notificar o Flutter de mudanças. Voltando ao editor de código, acessaremos a linha Text(counter.toString()) onde definimos o contador dentro do Text. Teremos que fazer o processo em seu interior de um jeito diferente, envolvendo o Widget Text com um Widget específico do GetX chamado Obx.

Utilizando o Widget Obx

Vamos posicionar o cursor em cima do Widget Text, pressionar "Ctrl+." e verificar na lista de sugestões a opção "Wrap with Widget" (envolver com Widget, em português). Isso gerará automaticamente um widget e seu child na linha do Text.

Inkwell(
    //Código omitido
)
widget(child: Text(counter.toString())),
// Código omitido

No lugar do widget, vamos dizer qual é o Widget que queremos utilizar: ou seja, o Obx.

Este não tem um child, mas sim uma função de callback, portanto, vamos deletar esse elemento e adicionar () =>. Vamos devolver para esse callback o nosso Text, utilizando a Observável com o toString.

Inkwell(
    //Código omitido
)
Obx(() => Text(counter.toString())),
// Código omitido

Salvaremos esse cartão e voltaremos para o emulador. Após isso, se pressionarmos o botão de "mais" ou de "menos", será possível adicionar e remover um item.

Resumidamente, toda vez que quisermos observar um Observável, precisamos utilizar o Widget Obx. Sem ele, não conseguimos notificar o Flutter de que houve mudanças e que ele precisa alterar no dispositivo o estado do componente ou variável alterada para depois redesenhar, por exemplo, o componente.

Ajustando o Contador

Vamos fazer um ajuste rápido no contador, pois quando pressionamos o botão de menos após o valor ser zero, o valor é reduzido para valores negativos. Não deveria ser possível fazer esse tipo de coisa num aplicativo de delivery.

Para realizar esse ajuste, acessaremos a função onTap do botão de remover, por volta da linha 50, onde há counter--.

Acima dessa linha, vamos criar a condição if counter > 0. Se o counter for maior que zero, podemos fazer counter--. Caso contrário, não vai acontecer nada.

InkWell(
    borderRadius: BorderRadius.circular(20),
    onTap: () {
        if(counter > 0){
            counter--;
        }
    },
    child: const Icon(
        Icons.remove_circle_outline,
        size: 20,
    ),
),

Salvaremos o cartao.dart e voltaremos ao emulador. Ao pressionar o botão de "menos" em um item com o valor zero, ele travará no zero e não exibirá mais os números negativos. Ainda conseguimos adicionar e remover, contanto que o valor seja maior que zero.

Após esse ajuste no contador, finalizamos essa parte da interação.

A seguir, veremos o que mais conseguimos fazer com o GetX. Nos veremos no próximo vídeo!

Sobre o curso Flutter: utilizando o Getx para gerenciamento de estados

O curso Flutter: utilizando o Getx para gerenciamento de estados possui 87 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Flutter acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas