Executando verificação de segurança...
2

De protótipo a produto: como usar o Flutter 3.22 para validar ideias em 48 horas

Sexta-feira, 16h. A pauta chega no Slack: “precisamos de um MVP para a feira na terça”. O designer já tem o Figma pronto, o PM quer ter algo tocável para validar com usuários e, claro, “é só um fluxo simples, né?”. Se você já passou por isso, sabe que “simples” é o código para “precisamos de milagre”. Há exatamente uma semana, o Google liberou o Flutter 3.22 com melhorias que tornam esse tipo de sprint não apenas possível, mas produtivo. Vou mostrar como transformei esse pedido em um app instalável em menos de dois dias sem cortar cantos que vão me cobrar juros depois.

Por que o Flutter 3.22 importa para MVPs

A versão trouxe duas mudanças discretas que mudam o jogo para quem precisa decolar rápido:

  1. Tamanho de bundle 15 % menor para Android sem nenhuma ação sua. Menos MB significa download mais rápido na loja interna da empresa e menos decepção quando alguém instala via QR-Code no estande.
  2. Hot reload 2x mais estável em telas que usam ListView aninhado. Se você já perdeu 20 minutos esperando o reload travar em um scroll infinito, sabe o valor disso.

Mas a cereja do bolo mesmo é o Material 3 ganhando padrão. Isso significa que widgets como Switch, Radio e Checkbox já nascem com a aparência do Android 14 e não precisam de customização para parecerem nativos. Economiza horas de CSS-zombie.

O roteiro de 48 horas que usei

Hora 0 - Clonar e colocar para rodar

flutter create feira_mvp --empty
cd feira_mvp
flutter pub add go_router flutter_bloc shared_preferences

Três dependências apenas. go_router para rotas declarativas, flutter_bloc para estado previsível e shared_preferences para mock de “login”. Nada de Firebase ou supabase; vamos tudo em memória.

Hora 1 - Converter o Figma em código

Com o Material 3 ativado, copiei os tokens de cor do Figma para o ColorScheme.light():

final theme = ThemeData(
  useMaterial3: true,
  colorScheme: ColorScheme.light(
    primary: const Color(0xFF005DFF),
    onPrimary: Colors.white,
    secondary: const Color(0xFFFF5D00),
  ),
);

Pronto: botões, chips e FAB já nascem com a paleta correta. Sem precisar escrever ElevatedButton.styleFrom em cada canto.

Hora 2 - Gerar o modelo com freezed

Criei o modelo de “Produto” em 30 segundos:

flutter pub add freezed_annotation dev:build_runner dev:freezed
@freezed
class Produto with _$Produto {
  factory Produto({
    required String id,
    required String nome,
    required double preco,
    @Default(false) bool favorito,
  }) = _Produto;
}

Um flutter pub run build_runner build e saíram 200 linhas de boilerplate que eu não precisei digitar.

Hora 4 - Lista fake com mocktail

Para não depender de backend, usei um repositório em memória:

final produtosMock = List.generate(
  12,
  (i) => Produto(
    id: 'p$i',
    nome: 'Produto ${i + 1}',
    preco: 19.9 * (i % 5 + 1),
  ),
);

Com mocktail, dá para trocar por API real depois sem tocar nas telas.

Hora 6 - Scroll que não trava

A lista tem imagens grandes; o Flutter 3.22 melhorou o ListView.builder com cacheExtent automático. Bastou envolver as imagens em CachedNetworkImage com placeholder:

CachedNetworkImage(
  imageUrl: produto.imagem,
  placeholder: (_, __) => const SkeletonAvatar(),
  errorWidget: (_, __, ___) => const Icon(Icons.broken_image),
  fit: BoxFit.cover,
)

O skeleton veio do pacote shimmer e deixou o loading parecendo Netflix.

Hora 8 - Navegação sem drama

Com go_router, declarei as rotas em 10 linhas:

final router = GoRouter(
  routes: [
    GoRoute(path: '/', builder: (_, __) => const ListaProdutos()),
    GoRoute(path: '/detalhe/:id', builder: (_, state) {
      final id = state.pathParameters['id']!;
      return DetalheProduto(id: id);
    }),
  ],
);

Deep-link funcionou de primeira. No estande, o PM conseguiu mandar “feira.app/detalhe/p3” por WhatsApp e abriu direto na tela.

Hora 10 - Estado local com Bloc simples

Evitei context.read() espalhado. Criei um ProdutosCubit que expõe apenas:

Future<void> toggleFavorito(String id) async {
  final index = state.indexWhere((p) => p.id == id);
  if (index >= 0) {
    final updated = state[index].copyWith(favorito: !state[index].favorito);
    emit([...state]..[index] = updated);
  }
}

Com HydratedBloc poderia persistir, mas para MVP ficou em memória. Reiniciar o app limpa tudo, o que é até bom para testes.

Hora 12 - Build release com flavor

Precisava de dois apps: um “demo” com dados engraçados para o estande e um “dev” com logs ligados. Configurei flavors no android/app/build.gradle:

productFlavors {
  demo { applicationIdSuffix ".demo" }
  dev  { applicationIdSuffix ".dev"  }
}

Comando para gerar APK do demo:

flutter build apk --flavor demo -t lib/main_demo.dart

APK de 9,8 MB, assinado com debug, mas suficiente para compartilhar via Firebase App Distribution.

Hora 24 - Testes de usabilidade na mesa do café

Instalei o APK em cinco aparelhos diferentes (um Moto G5 e um Galaxy A03 incluídos). O bundle menor fez diferença: 14 segundos de download no 3G do evento. Coletamos 22 gravações de tela com o Lookback e já tínhamos três insights reais para iteração.

Hora 36 - Ajustes rápidos

Com o hot reload estável, alterei o texto de um botão sem perder o scroll position. O designer pediu para trocar o ícone de favorito; foi só alterar Icons.favorite_border para Icons.bookmark_outline e rodar r no terminal. Zero travamento.

Hora 48 - Entrega

Segunda-feira, 17h30. Subi o .aab na Play Console em modo fechado, adicionei 20 e-mails da equipe e enviei o link. Na terça, às 9h, o app estava instalado em todos os tablets do estande. O feedback? “Parece que levou duas semanas”.

Lições que levo para o próximo MVP

  1. Menos é mais: Três dependências de produção são suficientes para validar.
  2. Material 3 é seu amigo: Use o que vem de fábrica; customiza depois.
  3. Flavors salvam vidas: Um comando alterna entre demo, dev e prod.
  4. Teste no lixo da gaveta: Se rodar num Moto G5, roda em qualquer lugar.
  5. Hot reload estável vale ouro: Flutter 3.22 entregou isso sem marketing barulhento.

Se a sua próxima sexta-feira parecer impossível, lembre-se: o Flutter 3.22 não faz café, mas transforma um Figma em um app instalável antes do fim de semana. E, quando o produto vingar, você já tem uma base que escala sem reescrever tudo.

Carregando publicação patrocinada...