Skip to main content

Boas Práticas | Flutter

  • Boas Práticas | Flutter

Este documento apresenta recomendações para manter consistência, clareza e qualidade de código em projetos Flutter/Dart.


1. Evite inicializar variáveis nulas explicitamente

Não é necessário inicializar variáveis nullable com null, pois esse já é o comportamento padrão do Dart.

Exemplo incorreto:

String? nome = null;

Exemplo correto:

String? nome;

Justificativa: o Dart já atribui null por padrão a variáveis não inicializadas e marcadas como opcionais (?). Evitar redundância melhora a legibilidade.


2. Nomeação de variáveis e constantes

Use lowerCamelCase para nomear variáveis, métodos e constantes locais, mantendo consistência com o estilo oficial do Dart.

Correto:

final String nomeCompleto = 'Adolfo Silva';
const int tempoPadrao = 60;

Incorreto:

final String NomeCompleto = 'Adolfo Silva';
const int TEMPO_PADRAO = 60;

Em Flutter, mesmo constantes podem seguir lowerCamelCase, a menos que sejam globais ou configurações fixas de ambiente, onde se pode usar SCREAMING_SNAKE_CASE.


3. Prefira StatelessWidget por padrão

Crie sempre as telas como StatelessWidget, e converta para StatefulWidget apenas quando for realmente necessário gerenciar estado (ex.: atualizações dinâmicas, animações, etc).

Correto:

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


Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Tela de Login')),
);
}
}

Somente use StatefulWidget quando:

  • A tela precisa reagir a eventos do usuário (ex.: mudar o estado de um botão).
  • Há interação com setState, AnimationController, ou StreamBuilder.

4. Classes e privacidade no Dart

No Dart, não existem modificadores de acesso como public ou private. A privacidade é definida por convenção, prefixando o nome com _ (underscore).

Exemplo:

class _MyPrivateClass {
final String nome = 'Privado';
}

Ao usar _ no nome da classe, método ou variável, ela se torna visível apenas dentro do mesmo arquivo. Esse é o comportamento equivalente a uma classe privada em outras linguagens.


5. Evite lógica de navegação dentro do método build()

Nunca adicione regras de redirecionamento ou navegação dentro do build(). O método build() deve ser puro e determinístico, retornando apenas widgets.

Exemplo incorreto:


Widget build(BuildContext context) {
if (!usuarioLogado) {
Navigator.of(context).pushReplacementNamed('/login');
}
return Scaffold(body: Text('Home'));
}

Exemplo correto:


void initState() {
super.initState();
_verificarLogin();
}

void _verificarLogin() {
if (!usuarioLogado) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushReplacementNamed('/login');
});
}
}

Justificativa: a navegação dentro do build() pode causar loops infinitos e erros de renderização, pois o build pode ser chamado diversas vezes pelo framework.


6. Outras recomendações úteis

  • Use const sempre que possível para widgets imutáveis — melhora a performance e reduz reconstruções.
  • Evite lógica complexa no build(). Extraia partes para métodos ou widgets auxiliares.
  • Comente apenas o necessário — código bem nomeado explica a si mesmo.
  • Evite valores mágicos (números ou strings soltos). Centralize-os em arquivos de constantes.

Exemplo:

const double espacoPadrao = 16.0;
const String mensagemErro = 'Ocorreu um erro inesperado.';

7. Resumo rápido

TemaBoa práticaExemplo correto
Variáveis nulasNão inicialize com nullString? nome;
NomeaçãoUse lowerCamelCasefinal nomeCompleto = '';
WidgetsPrefira StatelessWidgetclass LoginScreen extends StatelessWidget
Classes privadasUse _ como prefixo_MyPrivateClass
NavegaçãoFora do build()initState() + addPostFrameCallback()
ConstantesCentralize e use constconst double espacoPadrao = 8.0;