Alura > Cursos de Mobile > Cursos de Flutter > Conteúdos de Flutter > Primeiras aulas do curso Flutter: melhore a qualidade do app com design patterns

Flutter: melhore a qualidade do app com design patterns

Plano e padrões de projeto - Apresentação

Olá! Meu nome é Matheus Marcus, sou instrutor na Alura e vou te acompanhar nessa jornada.

Audiodescrição: Matheus se descreve como um homem branco, de cabelos castanho-escuros e lisos, e um risco na sobrancelha direita. Usa pequenas argolas pretas nas orelhas, veste uma camiseta preta estampada em branco e um colar de miçangas em tons de preto e marrom. À sua frente, um microfone. Ao fundo, luminárias azuis na parede.

Você já pensou em formas de melhorar a escrita do seu código, mas não sabe por onde começar? Tem dúvidas sobre como estruturar o seu projeto ou organizá-lo de maneira eficiente?

Neste curso, vou guiá-lo através dos conceitos de Design Patterns.

Juntos, vamos explorar esses conceitos enquanto desenvolvemos o Cinetopia, um aplicativo com quatro páginas:

Com este projeto, você aprenderá boas práticas de programação, conhecerá os fundamentos de Design Patterns com a arquitetura MVVM e terá uma introdução aos princípios SOLID.

Antes de seguir com este curso, é importante garantir que você atenda a alguns pré-requisitos, como ter conhecimentos fundamentais em Dart e estar familiarizado com o básico de Flutter.

Já domina esses conceitos? Então nos vemos no próximo vídeo!

Plano e padrões de projeto - Iniciando o projeto Cinetopia no Flutter

Neste curso, trabalharemos no desenvolvimento do Cinetopia, um aplicativo com quatro telas principais:

  1. Tela de introdução: a página inicial do aplicativo;
  2. Tela de filmes populares: apresenta uma lista de filmes em alta no momento, além de uma barra de busca para encontrar títulos específicos;
  3. Tela de descrição: ao clicar em um dos cartões de filmes, o usuário é direcionado para uma página com detalhes, como título, cartaz e data de lançamento;
  4. Tela de próximos lançamentos: exibe os filmes que em breve estarão disponíveis nos cinemas.

As informações como título, cartaz e data de lançamento serão obtidas de uma API, o que nos leva a uma questão importante: por onde começar o desenvolvimento? Devemos primeiro estruturar a lógica de comunicação com a API ou criar as telas e conectá-las depois?

Essas dúvidas são comuns ao aprender uma nova tecnologia ou linguagem, como o Flutter. A nossa recomendação é começar pelo básico e avançar gradualmente!

Criando o Projeto no VS Code

Para iniciar, vamos criar o projeto no VS Code. Primeiro, abrimos o terminal com o atalho "Ctrl + J" ou "Cmd + J". Em seguida, navegamos até a pasta de documentos usando o comando cd Documents. Depois, executamos o comando flutter create cinetopia para gerar a estrutura inicial do projeto.

Após a criação, abrimos a pasta do projeto clicando em "Open Folder" ou "Abrir Pasta" e selecionamos a pasta cinetopia.

Explorando a Estrutura do Projeto

Dentro da pasta do projeto, encontramos todas as informações necessárias para começar a desenvolver nosso aplicativo Flutter. Diferentemente do Dart, onde a pasta principal é a bin, no Flutter, a pasta principal é a lib.

Ao acessar a pasta lib, encontramos o arquivo main.dart, que já vem com um aplicativo padrão gerado automaticamente. No entanto, vamos criar nosso próprio aplicativo, o Cinetopia.

Para isso, podemos fechar o menu lateral esquerdo com o atalho "Ctrl + B" ou "Cmd + B" e apagar o conteúdo do arquivo main.dart, para depois iniciá-lo do zero. Esse exercício é essencial para compreender como o Flutter funciona!

Estruturando a Função main

É importante lembrar que o Flutter é um framework, e o Dart precisa da função main para executar qualquer código. A estrutura básica da função main é a seguinte:

void main() {
  runApp();
}

O editor de código sugere pacotes para importar a função runApp(). No nosso caso, utilizaremos o Material Design, que é o mais adequado para este projeto. Para isso, no topo do arquivo, incluímos o seguinte import:

import 'package:flutter/material.dart';

void main() {
  runApp(app);
}

A função runApp() requer um aplicativo como argumento, que ainda não criamos. Vamos fazer isso agora.

Criando o Widget Principal (Cinetopia)

Para criar o aplicativo, utilizamos um StatelessWidget. O Visual Studio Code facilita esse processo com o snippet stl. Basta digitá-lo e pressionar "Enter" que a estrutura será criada.

Nomearemos o widget como Cinetopia e, no método build(), retornamos um MaterialApp no lugar do Placeholder. O MaterialApp precisa de algumas propriedades básicas para funcionar. Podemos começar com o título do aplicativo:

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Cinetopia",
    );
  }
}

Configurando o Tema

Além disso, adicionamos um tema ao aplicativo. Como ele será exibido no modo escuro (dark mode), configuramos a propriedade theme usando ThemeData. Esse objeto encapsula as informações essenciais para personalizar a aparência do aplicativo, como o controle do brightness.

A propriedade brightness permite definir o tema do aplicativo, alternando entre dark mode e light mode. Por exemplo, podemos configurar o dark mode utilizando brightness: Brightness.dark. Além disso, temos a opção de adotar o Material Design 3 para um design mais moderno e atualizado.

O parâmetro colorSchemeSeed define a cor base que será utilizada para gerar a paleta de cores do aplicativo. Para facilitar a leitura do código, adicionamos uma vírgula ao final da configuração de ThemeData, alinhando os parâmetros de forma mais organizada.

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Cinetopia",
      theme: ThemeData(
        brightness: Brightness.dark,
        useMaterial3: true,
        colorSchemeSeed: Colors.deepPurple,
      ),
    );
  }
}

Criando a Página Inicial (HomePage)

A próxima etapa é adicionar a propriedade home, que define a página inicial do aplicativo. Para isso, criamos uma nova página como um StatelessWidget chamada HomePage. No método build, retornamos um Scaffold(), que serve como a estrutura básica de uma página no Flutter. O código da HomePage fica assim:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

O Scaffold() serve como a estrutura básica da página, garantindo a utilização completa dos recursos do Material Design. Ele exige algumas propriedades essenciais e, neste caso, vamos definir apenas o body, que representa o corpo da página.

Dentro do body, utilizaremos um Center(), um widget que centraliza o conteúdo na tela. Esse Center() conterá um child, que será um Text(), ou seja, um widget de texto. No Text(), podemos adicionar algo simples, como "Hello World".

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Hello World"),
      ),
    );
  }
}

Finalizando a Estrutura

No MaterialApp, configuramos a propriedade home para usar a HomePage.

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Cinetopia",
      theme: ThemeData(
        brightness: Brightness.dark,
        useMaterial3: true,
        colorSchemeSeed: Colors.deepPurple,
      ),
      home: HomePage(),
    );
  }
}

Por fim, na função runApp(), passamos o nosso aplicativo Cinetopia:

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

Após salvar o arquivo, executamos o aplicativo e mantemos o emulador aberto. O resultado esperado é uma tela exibindo o texto "Hello World".

Considerações Finais e Próximos Passos

Essa abordagem nos permite começar de forma simples, estabelecendo a base do aplicativo. Com a estrutura inicial pronta, podemos avançar para estilização e lógica. Primeiro, criamos algo funcional e visível.

Prontos para o próximo passo? Vamos desenvolver nossa primeira página!

Plano e padrões de projeto - Construindo uma tela com o botão InkWell

Qual seria o nosso próximo passo? Vamos analisar nosso Figma.

Dentro do Figma, a primeira tela que temos assim que a pessoa abre o aplicativo é a página inicial do Cinetopia. Essa página possui um logotipo, uma imagem de pessoas assistindo a um filme, um texto e um botão.

Imagem de uma tela do aplicativo 'cinetopia' com fundo roxo escuro e três personagens animados sentados em poltronas de cinema. Os personagens são estilizados com grandes cabeças, pequenos corpos e cores vibrantes. No topo, o nome 'cinetopia' é apresentado em letras brancas com estilo de título de filme. Abaixo dos personagens, o texto em branco diz 'O lugar ideal para buscar, salvar e organizar seus filmes favoritos!'. Na parte inferior, há um botão retangular com bordas arredondadas e o texto 'Quero começar!' seguido por uma seta indicando a direção para a direita, indicando o call to action para iniciar o uso do aplicativo.

Vamos implementar essa estrutura em nosso código.

No VSCode, precisaremos das imagens que serão inseridas no projeto. Você pode pegar esses arquivos na atividade "Preparando o ambiente", pode pausar este vídeo caso ainda não tenha feito isso.

Baixe o arquivo Zip, extraia e cole todo o conteúdo da pasta "assets" na raiz do projeto. A pasta "assets" deve ser copiada, extraída e colocada na raiz do projeto.

Não basta apenas inserir os arquivos para que tudo funcione. Vamos ao arquivo pubspec.yaml adicionar essas dependências ao nosso projeto.

Perto da linha 64, 63, há um comentário explicando como adicionar "Assets" ao projeto.

# To add assets to your application, add an assets section, like this:
# assets:
#  - images/a_dot_burr.jpeg
#  - images/a_dot_ham.jpeg

Pularemos duas linhas e adicionaremos conforme o exemplo. Inserindo o caminho das imagens.

assets:
  - assets/logo.png
  - assets/movie.png
  - assets/popular.png
  - assets/splash.png
  - assets/upcoming.png

É importante manter os espaçamentos corretos, pois este arquivo é um YAML e é sensível à indentação. Assim que salvarmos o arquivo, provavelmente aparecerá uma notificação no canto inferior direito indicando que as dependências foram atualizadas.

Caso não tenham sido, ou se houver dúvidas, podemos pressionar "Command + J" ou "Ctrl + J" para abrir o terminal e executar o seguinte comando. Isso resolverá as dependências.:

flutter pub get

Com as dependências resolvidas, podemos acessar o arquivo main.dart e focar na nossa homepage.

Temos duas imagens: o logotipo e a splash, além de um texto e um botão. Vamos substituir o body por algo como um column. O column indica que haverá um elemento abaixo do outro. Ele possui uma propriedade chamada children, que é uma lista de widgets.

Nosso primeiro widget será um Image.asset, e passaremos o caminho definido no pubspec. Depois, temos um texto: "O lugar ideal para buscar, salvar e organizar seus filmes favoritos!".

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      children: <Widget>[
        Image.asset("assets/logo.png"),
        Image.asset("assets/splash.png"),
        Text("O lugar ideal para buscar, salvar e organizar seus filmes favoritos!"),
      ],

Botão

Por último, temos um botão. Este botão tem um detalhe importante. Provavelmente você já conhece o ElevatedButton, mas não o utilizaremos. Vamos usar outro widget. Primeiro, vejamos como ele fica com o ElevatedButton:

ElevatedButton(
  onPressed: () {},
  child: Text("Quero começar!"),
),

Ao salvar o arquivo e verificar no emulador, o botão possui uma cor de fundo diferente do Figma, e ao clicar, há um efeito de onda. Por que não usar esse botão? Precisamos de algo que atenda ao design do Figma. É mais fácil pegar algo vazio e preencher com o necessário do que apagar estilizações prontas!

O ElevatedButton é um Material Widget, seguindo padrões do Material Design da Google. Usaremos algo semelhante, próximo ao Flutter Widget, que é mais puro, sem estilizações. O GestureDetector, por exemplo, não possui efeito visual, mas a Google criou outro widget que só tem o efeito, sem estilização. Podemos usá-lo com nosso Flutter Widget.

No editor de código, trocaremos ElevatedButton por InkWell, mantendo as outras propriedades. onPressed será onTap no InkWell.

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Column(
      children: <Widget>[
        Image.asset("assets/logo.png"),
        Image.asset("assets/splash.png"),
        Text("O lugar ideal para buscar, salvar e organizar seus filmes favoritos!"),
        InkWell(
          onTap: () {},
          child: Text("Quero começar!"),
        ),
      ],

Ao salvar e verificar no simulador, o efeito de ripple permanece, mas sem estilizações. Para adicionar bordas arredondadas e cor de fundo, usaremos um Container.

No Visual Studio Code, o child não será apenas um texto, mas um Container. Dentro dele, usaremos um Row para o texto e ícone, lado a lado:

InkWell(
  onTap: () {},
  child: Container(
    decoration: BoxDecoration(
      color: Color(0xFFB370FF),
      borderRadius: BorderRadius.circular(50),
    ),
    child: Row(
      children: <Widget>[
        Text("Quero começar!"),
        Icon(Icons.arrow_forward),
      ],

Ao salvar e verificar no simulador, o botão aparece com o efeito de ripple. Contudo, o efeito parece ocorrer por trás do botão. Isso ocorre devido à ordem de desenho das camadas. O Container é desenhado por cima de tudo, então o efeito de ripple fica atrás. Para resolver, usaremos o Ink, que funciona como um Container, mas sem problemas de sobrescrita do efeito de ripple do InkWell.

No VSCode, trocaremos Container por Ink.

Ao salvar e verificar no simulador, o efeito de ripple ocorre corretamente.

Próximo passo

Definimos a estrutura, e o próximo passo será estilizar a página para que fique como no Figma!

Sobre o curso Flutter: melhore a qualidade do app com design patterns

O curso Flutter: melhore a qualidade do app com design patterns possui 163 minutos de vídeos, em um total de 73 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