Widgets Escondidos do Flutter que Deixam seu App com Acabamento de Nível Sênior

O Flutter tem muitos widgets. Alguns são chamativos (Hero, AnimatedContainer). Alguns são famosos (ListView, Stack). E existem os heróis silenciosos — widgets que ficam ali no canto, te julgando, esperando pelo dia em que você finalmente precisará deles.

Hoje, vamos falar sobre quatro dessas joias subestimadas:

  • Baseline
  • Offstage
  • DecoratedBox
  • PhysicalModel

Esses widgets não gritam por atenção — mas, quando você precisa deles, nada mais serve.

1. Baseline — Porque o Texto Também Tem Sentimentos.

Já tentou alinhar números, textos ou símbolos em uma linha (Row) e sentiu que algo estava simplesmente… estranho? Isso acontece porque o texto também tem sentimentos — ele se alinha em uma linha invisível chamada baseline (linha de base). O widget Baseline permite que você alinhe textos (ou até ícones) perfeitamente, sem precisar de adivinhação com paddings ou gambiarras.

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Text("With Padding"),
    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          'x',
          style: TextStyle(fontSize: 28),
        ),
        Padding(
          padding: const EdgeInsets.only(bottom: 12),
          child: Text(
            '2',
            style: TextStyle(fontSize: 14),
          ),
        ),
      ],
    ),

    SizedBox(height: 20), 
    Text("With Baseline"),
    Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          'x',
          style: TextStyle(fontSize: 28),
        ),
        Baseline(
          baseline: 12, 
          baselineType: TextBaseline.alphabetic,
          child: Text(
            '3',
            style: TextStyle(fontSize: 14),
          ),
        ),
      ],
    ),
  ],
)

Sem gambiarras de padding.
Sem números mágicos empilhados sobre números mágicos.
Apenas o baseline fazendo o que o baseline faz de melhor.

2. Offstage — O Widget que Existe… Mas Não Existe.

O Offstage é como aquele estagiário que está tecnicamente na folha de pagamento, mas não aparece nas reuniões.
Ele constrói o widget e mantém o seu estado — mas não o renderiza (não pinta na tela) nem ocupa espaço.

Usando if (O Estado é Destruído

if (showLoader)
  CircularProgressIndicator();

Usando Offstage

Offstage(
  offstage: !showLoader,
  child: CircularProgressIndicator(),
)

O Offstage é “sorrateiramente” bom porque mantém o widget vivo na árvore de widgets sem ocupar nenhum espaço no layout ou exigir novas renderizações desnecessárias. Isso o torna perfeito para telas pré-carregadas, animações esperando o momento certo ou formulários que você não quer que sejam resetados por acidente. Pense nele como um widget que diz: “Esteja pronto, mas fique escondido”.

3. DecoratedBox — Quando você não precisa de um Container.

Seja honesto. Você já escreveu isso vezes demais:

Container(
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(12),
  ),
)

Mas e se você só precisar da decoração?
Apresento a você o DecoratedBox.

DecoratedBox(
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(12),
  ),
  child: Padding(
    padding: const EdgeInsets.all(16),
    child: Text(
      'I am lighter than Container',
      style: TextStyle(color: Colors.white),
    ),
  ),
)

Se você não precisa de margem, constraints ou alinhamento — não invoque o deus Container.

4. PhysicalModel — Sombras Reais, Não Fake.

O BoxShadow até que quebra o galho… até que deixa de ser suficiente.

Se você quer elevação real, recorte (clipping) e sombras que se comportam como o Material Design — o PhysicalModel é o seu melhor amigo.

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    SizedBox(width: double.infinity),
    Container(
      decoration: BoxDecoration(
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            blurRadius: 10,
            color: Colors.black26,
          ),
        ],
        borderRadius: BorderRadius.circular(16),
      ),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Text('Real shadow. Real power.'),
      ),
    ),
    SizedBox(height: 15),
    PhysicalModel(
      color: Colors.white,
      elevation: 8,
      shadowColor: Colors.black,
      borderRadius: BorderRadius.circular(16),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Text('Real shadow. Real power.'),
      ),
    ),
  ],
)

Se você precisa de mais controle sobre as sombras — como personalizar a propagação (spread), o desfoque (blur) ou a cor — o BoxShadow dentro de um DecoratedBox é a sua escolha ideal. Mas, se você quer apenas uma sombra rápida e realista, com elevação e recorte (clipping) adequados, o PhysicalModel resolve o problema em segundos.

Se isso te ajudou, considere compartilhar com um colega desenvolvedor. Para mais descobertas como esta, clique em seguir — e até a próxima, bons códigos (ou happy Fluttering)!

Please follow and like us:
error0
fb-share-icon
Tweet 20
fb-share-icon20