Alura > Cursos de Mobile > Cursos de Flutter > Conteúdos de Flutter > Primeiras aulas do curso Flutter: aplicando gerenciamento de estados com MobX

Flutter: aplicando gerenciamento de estados com MobX

Gerenciamento de estados em Flutter - Apresentação

Boas-vindas! Sou Matheus Alberto, instrutor da Escola de Mobile na Alura.

Autodescrição: Sou um homem branco de cabelos castanhos escuros curtos. Tenho olhos castanhos escuros e estou com a barba feita. Estou vestindo uma camiseta azul escura. Ao fundo, há uma parede lisa azul clara.

O que vamos aprender?

Neste curso, vamos desenvolver um aplicativo de delivery chamado Panucci Delivery. Nele, podemos adicionar itens na sacola de compras e conferir o valor total na parte inferior da tela. Clicando no botão "Ver carrinho", seremoss redirecionados para a página de checkout, onde é possível validar os itens escolhidos e finalizar o pedido.

Trabalharemos com gerenciador de estados MobX. Estudaremos conceitos como actions e observables (observáveis). Também aprendemos como recuperar as informações dos observáveis e transportá-los para toda nossa aplicação, utilizando provider.

Gerenciadores de estado são muito utilizados no mercado de trabalho, porque facilitam bastante o processo de lidar com variáveis e objetos mutáveis que precisam ter algum tipo de reflexo na parte visual da aplicação. Por exemplo, caso um valor seja atualizado e precisemos de uma ação refletida na tela, os gerenciadores de estado são uma ótima ferramenta para facilitar esse trabalho.

Pré-requisito

O único pré-requisito para este curso é que você tenha conhecimento de gerenciadores de estado com provider. É interessante saber como passar informações de provider com as telas, principalmente com relação ao context.

Espero ter despertado seu interesse! Te convido para participar dessa aventura comigo. Vamos mergulhar nesse mar de conhecimento?

Gerenciamento de estados em Flutter - Conhecendo o projeto

É importante que, neste momento do curso, você já tenha baixado os arquivos do projeto. Caso não tenha feito isso ainda, recomenda-se voltar à atividade anterior e baixar os arquivos antes de prosseguir.

Depois de baixados e extraídos em uma pasta, vamos conferir como é a estrutura do projeto em uma IDE. No caso, estou usando o Visual Studio Code, mas você pode utilizar a de sua preferência. Executando o arquivo main.dart (na pasta "lib"), podemos conferir no emulador como está o projeto atualmente.

Tela inicial

No topo da tela, há um campo de busca. Na parte central da tela, há três categorias. De cima para baixo, são elas: "Mais comprados", "Para o almoço" e "Para dividir". Abaixo de cada categoria, há cartões de produtos dispostos horizontalmente. Cada cartão contém uma imagem, o nome do produto, um valor em reais e a quantidade adicionada ao carrinho (por padrão, zero). Na parte inferior, há um botão vermelho escrito "Ver carrinho" no centro. Na parte esquerda do botão, há um ícone de cesta com o número de itens no carrinho. Na parte direita, há o valor total em reais.

O que cada um dos componentes na tela representa está dentro da pasta "lib", em que temos as subpastas:

Além disso, temos um arquivo chamado cardapio.dart, que contém todas as informações necessárias para preencher as listas de cada categoria da aplicação, como "Mais comprados", "Para o almoço" e "Para dividir". Dentro dessas listas, temos os nomes de cada um dos cartões, a qual categoria ela pertence, qual seu valor e a URL da imagem.

O componente mais importante com o qual vamos trabalhar é o cartao.dart, porque ele engloba toda a estrutura da imagem, do nome do produto, do preço e do contador, que é um componente separado cuja única responsabilidade é adicionar e remover itens do carrinho de compras.

A estrutura do arquivo contador.dart é bem simples. Temos o botão de remover, o texto que indica a quantidade e o botão de adicionar. Atualmente, esses botões não estão funcionais. Vamos trabalhar neles ao longo do curso.

Ao adicionar ou remover itens do carrinho, queremos mostrar a quantidade de itens e o valor total da compra na parte de baixo da tela. Esse componente está no final do arquivo home.dart, na pasta "screens".

Ele recebe a quantidade de itens na sacola, exibe o texto "Ver carrinho" e também mostra o valor total da compra. Trata-se de funcionalidades que também implementaremos no curso.

Tela de checkout

Ao clicar no botão "Ver carrinho" na parte inferior, a pessoa usuária será direcionada para a página de checkout. Como nós ainda não implementamos a navegação, não conseguiremos acessá-la pelo emulador agora, mas podemos conferir seu leiaute no Figma.

Na tela de checkout, temos a seção "Pedido" com a lista de itens adicionados no carrinho. Em seguida, temos a seção "Pagamento", em que é possível selecionar um cartão. Depois, temos a seção "Confirmar", com o valor final da compra. Na parte inferior, há um botão vermelho escrito "Pedir". Todos esses componentes estão na pasta "components" e no arquivo checkout.dart (na pasta "screens").

É importante que você tenha o Flutter na versão 3.7.1. No arquivo pubspec.yaml, a partir da linha 30, temos as seguintes dependências:

A partir da linha 42, temos as seguintes dependências de desenvolvimento:

É necessário que você tenha todas essas dependências nas versões mencionadas nesse arquivo. A IDE provavelmente as baixará automaticamente, mas, caso não faça, basta abrir o terminal e rodar o seguinte comando:

flutter pub get

Feito isso, podemos seguir com o nosso projeto.

Gerenciamento de estados em Flutter - Estados com setState

Vamos começar fazendo o nosso cartão adicionar itens na sacola, então trabalharemos no componente de contador. No arquivo contador.dart, temos duas funções: adição e remoção de itens.

Já que queremos alterar um valor que será refletido depois na tela, vamos usar um StatefulWidget. Portanto, na linha 3, vamos converter o StatelessWidget para o StatefulWidget:

class Contador extends StatefulWidget

Agora, precisamos de algum lugar para guardar as informações de quantidade de itens selecionados. Dentro do contador, vamos criar uma variável do tipo inteiro chamada valorContador, inicializada com o valor zero:

// ...

class _ContadorState extends State<Contador> {
  int valorContador = 0;

// ...

Toda vez que quisermos fazer uma alteração nessa variável e ela ser refletida na aplicação, o primeiro passo é mostrá-la na tela. Atualmente, na linha 24, temos um Text com valor fixo igual a 0 em string. Alteraremos esse valor para utilizar a variável valorContador:

// ...

Text(valorContador.toString())

// ...

Como o Text só recebe textos, usamos o método toString() para converter o número inteiro em string. Podemos salvar as alterações e notaremos que a aplicação continua funcionando.

Botão de remoção

O primeiro botão é responsável pela remoção de um item. Para alterar o valor da variável e espelhá-lo na tela, dentro de onTap(), usaremos a função setState(). Como estamos subtraindo do contador, colocaremos valorContador--:

// ...

InkWell(
    borderRadius: BorderRadius.circular(20),
    onTap: () {
        setState(() {
                valorContador--;
        });
    },
    child: const Icon(Icons.remove_circle_outline, size: 20,),
),

// ...

O valor inicial é zero e não pretendemos usar números negativos. Então, vamos inserir uma estrutura if para garantir que esse botão só funcionará se o valor for maior que zero:

// ...

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

// ...

Ao salvar as alterações, notaremos que a aplicação continua funcionando.

Botão de adição

No segundo botão, vamos desenvolver a lógica para adicionar um item ao carrinho. Similarmente ao anterior, usaremos a função setState() com valorContador++:

// ...

InkWell(
    borderRadius: BorderRadius.circular(20),
    onTap: () {
        setState(() {
                valorContador++;
        });
    },
    child: const Icon(Icons.add_circle_outline, size: 20,),
),

// ...

Vamos salvar e testar. No emulador, ao clicar nos botões de remoção e adição de um produto, o número do contador será atualizado na tela.

Limitações da aplicação

Por enquanto, conseguimos trabalhar usando o StatefulWidget. No entanto,encontraremos algumas limitações na nossa aplicação. Por exemplo, o valor do contador está sendo utilizado apenas dentro do widget de contador. Ele apenas modifica o número exibido, mas não insere um item no carrinho nem altera a lista de compras, de fato.

Além disso, as funções de remoção e adição simplesmente incrementam ou decrementam um valor, a partir do próprio botão que é acessível apenas dentro do contador. E se quisermos acessar essa função em outros lugares da aplicação para alterar a quantidade de um item?

Não bastasse, os valores que aparecem na parte inferior da tela são globais, que devem ser acessíveis de qualquer lugar a aplicação. Ao adicionar um item na sacola, por exemplo, tanto a quantidade de itens quanto o valor total em reais deveria ser modificado.

E como passamos todos esses valores para outras telas? Na página de checkout, temos uma lista de tudo que pretendemos comprar, bem como o valor total do carrinho.

Com o Flutter, conseguimos resolver essas questões com InheritedWidget e até mesmo com StatefulWidget. Contudo, à medida que aplicação fica mais complexa, torna-se difícil manter o controle de onde utilizaremos cada função e como passamos informações de um widget a outro de maneira consistente e evitando problemas de duplicidade.

Uma forma melhor de lidar com todos esses problemas é o uso de gerenciadores de estados. Eles lidam com todos os estamos de várias partes da aplicação, assim temos um controle mais tranquilo e agradável. No próximo vídeo, aprenderemos sobre esse assunto.

Sobre o curso Flutter: aplicando gerenciamento de estados com MobX

O curso Flutter: aplicando gerenciamento de estados com MobX possui 98 minutos de vídeos, em um total de 46 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