flowchart LR
M1[01 Ambiente<br/>e Flutter] --> M2[02 Dart<br/>e domínio]
M2 --> M3[03 Widgets<br/>e árvore]
M3 --> M4[04 Layout<br/>e responsividade]
M4 --> M5[05 Navegação<br/>go_router]
M5 --> M6[06 Formulários<br/>e validação]
M2 -.modelos.-> M6
M3 -.estado.-> M6
Resumo de Estudo — Módulos 01 a 06
Este é um resumo para você revisar hoje, antes da atividade de recuperação de amanhã. Ele não substitui os materiais completos dos seis módulos, mas reúne a coluna vertebral de cada um deles: o que de fato importa entender, onde a maioria dos colegas tropeça e como os conceitos se encaixam. Leia com o material original ao lado nos pontos em que você se sentir inseguro, e, se puder, com o emulador aberto, porque reler Flutter sem digitar Flutter é a forma mais lenta de aprender Flutter. A ideia é que, ao terminar esta leitura, você tenha o mapa inteiro na cabeça e saiba exatamente quais trechos do material precisa reabrir.
Como aproveitar este resumo hoje. Percorra cada seção e marque os conceitos que ainda parecem nebulosos. Para cada marca, volte ao módulo correspondente e estude só aquele ponto. Estudar é estreitar o foco no que falta, não reler tudo de novo do começo.
O fio que liga os seis módulos
Os módulos não são tópicos soltos. Eles constroem, em ordem, um aplicativo que sai do nada e chega a uma interface navegável que coleta dados do usuário com segurança. Entender essa progressão é metade da revisão, porque boa parte das dúvidas não nasce de um módulo isolado, e sim de ter perdido o encadeamento entre eles.
Módulo 01 — Ambiente e a natureza do Flutter
O primeiro módulo parece o mais simples e é onde se acumula uma dívida silenciosa: um ambiente mal configurado contamina todos os módulos seguintes, porque erros de SDK ou de emulador acabam confundidos com erros do seu próprio código. No plano conceitual, o que precisa estar firme é por que o Flutter desenha cada pixel por conta própria, em vez de pedir componentes ao sistema operacional. É isso que garante aparência e comportamento idênticos no Android e no iOS a partir de um único código Dart. Guarde a frase que volta em todos os módulos: no Flutter, a interface é uma função do estado. A tela é o resultado de uma descrição declarativa, e quando o estado muda, o Flutter recalcula essa descrição e reconcilia o que mudou.
Módulo 02 — Dart e os modelos do domínio
Dart é a fundação; sem fluência aqui, o resto vira tentativa e erro. Três pilares precisam estar sólidos. O primeiro é o null safety: a diferença entre String e String? é o compilador te protegendo do erro mais comum em aplicativos, o acesso a um valor que não existe. O segundo são os construtores nomeados e a imutabilidade pelo copyWith, que cria uma cópia de um objeto alterando apenas um campo, sem mutar o original. O terceiro é a sobrescrita de ==, hashCode e toString, que faz seus objetos se compararem por valor, e não por identidade de memória.
É no Módulo 02 que nasce o coração do aplicativo. Revise a forma de uma entidade nas duas versões que sempre trabalhamos:
class Tarefa {
final String id;
final String titulo;
final bool concluida;
Tarefa({
required this.id,
required this.titulo,
this.concluida = false,
});
Tarefa copyWith({String? titulo, bool? concluida}) {
return Tarefa(
id: id,
titulo: titulo ?? this.titulo,
concluida: concluida ?? this.concluida,
);
}
@override
bool operator ==(Object other) =>
other is Tarefa && other.id == id;
@override
int get hashCode => id.hashCode;
}class Tarefa {
final String id;
final String titulo;
final bool concluida;
const Tarefa({required this.id, required this.titulo, this.concluida = false});
Tarefa copyWith({String? titulo, bool? concluida}) => Tarefa(
id: id,
titulo: titulo ?? this.titulo,
concluida: concluida ?? this.concluida,
);
@override
bool operator ==(Object o) => o is Tarefa && o.id == id;
@override
int get hashCode => id.hashCode;
}Note que o modelo fica em Dart puro, sem nenhuma importação de Flutter. Essa disciplina é a semente da arquitetura que você verá adiante: o domínio não conhece a interface.
Módulo 03 — Widgets e a árvore
O conceito que precisa fazer clique é que tudo é widget e que widgets se organizam em uma árvore: um Text dentro de um Column, dentro de um Scaffold, dentro de um MaterialApp. A distinção que mais gera dúvida é entre StatelessWidget e StatefulWidget. O primeiro não tem memória: dado o mesmo input, desenha sempre a mesma coisa. O segundo guarda estado mutável e se redesenha quando você chama setState. A regra prática é simples: se algo na tela muda em resposta a uma interação e precisa ser lembrado, é StatefulWidget; caso contrário, prefira StatelessWidget, que é mais leve.
O setState não atualiza a tela por mágica. Ele marca o widget como sujo e pede ao Flutter que reconstrua aquele ramo da árvore. Por isso ele só existe em StatefulWidget, e por isso colocar lógica pesada dentro do build é um erro: build roda muitas vezes.
Módulo 04 — Layout e responsividade
É o módulo dos temidos avisos de overflow, e a causa quase sempre é a mesma: não interiorizar a regra de ouro do Flutter, segundo a qual as restrições descem pela árvore, os tamanhos sobem e o pai posiciona o filho. O pai informa quanto espaço o filho pode ocupar; o filho decide seu tamanho dentro desse limite; o pai então o posiciona. Row e Column organizam filhos na horizontal e na vertical; Expanded faz um filho ocupar o espaço restante e Flexible permite que ele encolha. O overflow listrado quase sempre significa conteúdo maior que a tela sem um widget de rolagem, como ListView ou SingleChildScrollView.
Diagnóstico rápido de overflow: o conteúdo é uma lista que pode crescer? Use ListView. É uma coluna que às vezes não cabe? Envolva em SingleChildScrollView. É uma divisão proporcional de espaço fixo? Use Expanded e Flexible.
Módulo 06 — Formulários, validação e feedback
O sexto módulo amarra tudo: usa os modelos do 02, o estado do 03 e a navegação do 05 para capturar dados com segurança. O eixo é o widget Form, que coordena os campos e oferece validação centralizada por meio de uma GlobalKey<FormState>. Cada TextFormField recebe um validator, uma função que retorna null quando o valor é válido ou uma mensagem de erro quando não é. O ciclo a internalizar é: o usuário preenche, você chama validate(), o Flutter dispara todos os validadores e só prossegue se todos retornarem null. Validar é a fronteira que impede dados inconsistentes de entrarem no domínio, e o feedback ao usuário, como um SnackBar de confirmação ou uma mensagem sob o campo, faz parte da validação: um erro silencioso é tão ruim quanto um dado inválido aceito.
Para fechar o estudo de hoje
Você não precisa reler os seis materiais inteiros hoje — isso não funciona e cansa à toa. Use este resumo para localizar suas lacunas e abra apenas os trechos correspondentes nos materiais originais. Antes de encerrar, faça um teste honesto consigo mesmo: consegue explicar, em voz alta e sem olhar, o que torna um widget stateful, por que ocorre um overflow, como uma rota nomeada conecta duas telas e o que um validator faz? Cada pergunta que você travar é exatamente o módulo que merece sua atenção nas próximas horas. Chegue amanhã com esses quatro pontos firmes e o resto se apoia neles.