Skip to main content


Widgets


No Flutter, o widget é uma peça da interface, um texto é um widget, um botão é um widget, uma tela é um widget, um espaçamento é um widget, uma coluna é um widget. Até a aplicação inteira começa por um widget.


Por isso é comum ouvir que no Flutter quase tudo é widget. A ideia é que a tela seja montada juntando pequenas peças. Em vez de escrever uma tela separada em XML, HTML ou usar um editor visual, o Flutter monta a interface usando código Dart.


Um exemplo simples:

Text('Servidor ativo')

Esse código cria um widget de texto.


Agora, se quisermos centralizar esse texto:

Center(
child: Text('Servidor ativo'),
)

Aqui temos dois widgets:

Center
└── Text

O Center é um widget que centraliza outro widget. O Text é o widget que mostra o texto. Essa ideia de um widget dentro de outro é a base do Flutter.



Widget como árvore


A interface no Flutter é formada como uma árvore.

MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Servidores'),
),
body: Center(
child: Text('Servidor ativo'),
),
),
)

Cada parte tem uma responsabilidade.

  • O MaterialApp configura a aplicação.
  • O Scaffold cria a estrutura básica da tela.
  • O AppBar cria a barra superior.
  • O body define o conteúdo principal da tela.
  • O Center centraliza o conteúdo.
  • O Text mostra o texto.

Então, quando a tela aparece, ela não surge de um único bloco. Ela é o resultado de vários widgets combinados.



Widgets de conteúdo e widgets de layout


Nem todo widget tem a mesma função, alguns widgets mostram conteúdo, como:

Text('Servidor Web')

E:

Icon(Icons.storage)

Outros widgets organizam a tela:

Column()
Row()
Center()
Padding()
SizedBox()
Container()

Por exemplo:

Padding(
padding: EdgeInsets.all(16),
child: Text('Servidor Web'),
)

O Padding adiciona espaço ao redor do Text. A estrutura fica assim:

Padding
└── Text

O Padding não mostra um texto próprio. Ele só altera o espaço ao redor do widget filho.



StatelessWidget


O StatelessWidget é um widget sem estado interno, ou seja, ele é usado para montar uma parte da interface que não precisa guardar dados que mudam durante o uso da tela.


Por exemplo, uma tela que apenas mostra informações fixas pode ser um StatelessWidget:

Text('Servidor Web')

Esse texto não muda sozinho. Ele apenas aparece na tela. Agora pensando em uma tela simples de detalhes de servidor:

Nome: Servidor Web
IP: 192.168.0.10
Status: Ativo

Se esses dados forem recebidos prontos e a tela só precisar mostrar eles, um StatelessWidget já resolve.



Quando usar StatelessWidget


Use StatelessWidget quando a tela ou parte da tela não precisa mudar por conta própria, como:

  • Tela de apresentação
  • Cabeçalho fixo
  • Card de servidor já preenchido
  • Texto de aviso
  • Botão que apenas chama uma ação externa
  • Layout fixo
  • Tela que recebe dados prontos e só mostra

O StatelessWidget não significa que os dados nunca mudam. Um StatelessWidget não guarda estado interno, mas ele pode receber dados diferentes de fora, exemplo:

CardServidor(
nome: 'Servidor Banco',
ip: '192.168.0.20',
status: 'Inativo',
)

Aqui usamos o mesmo CardServidor, só que com outros valores. O widget continua sendo sem estado, porque ele não controla a mudança. Ele só recebe os dados e mostra. A mudança vem de fora.



StatefulWidget


O StatefulWidget é um widget com estado, ou seja, ele é usado quando a tela, ou uma parte da tela, precisa guardar algum dado que pode mudar durante o uso da aplicação.


Por exemplo:

Status: Ativo

Se esse status puder mudar para:

Status: Inativo

Então a tela precisa guardar o valor atual do status em algum lugar. Nesse caso, usamos um StatefulWidget.



O que é estado?


O estado é qualquer informação que a interface precisa lembrar enquanto a aplicação está rodando. Exemplos de estado:

  • texto digitado em um campo
  • item selecionado em uma lista
  • status atual de um servidor
  • contador de cliques
  • checkbox marcado ou desmarcado
  • lista de servidores carregada na tela
  • mensagem de erro exibida no formulário

No caso de um app de servidores, podemos ter um estado assim:

String status = 'Ativo';

Esse valor começa como Ativo, mas pode mudar depois para Inativo.



Quando usar StatefulWidget


Use o StatefulWidget quando a tela precisa guardar alguma informação que muda durante o uso, como:

  • Tela de cadastro com campos preenchidos
  • Tela com botão que altera status
  • Tela com contador
  • Tela com checkbox
  • Tela com carregamento de dados
  • Tela com lista que recebe novos itens
  • Tela com mensagem de erro ou sucesso


Quando não usar StatefulWidget


Não precisamos usar StatefulWidget quando a parte da tela só recebe dados e mostra. Por exemplo, este card pode continuar sendo StatelessWidget:

class CardServidor extends StatelessWidget {
final String nome;
final String ip;
final String status;

const CardServidor({
super.key,
required this.nome,
required this.ip,
required this.status,
});

@override
Widget build(BuildContext context) {
return ListTile(
title: Text(nome),
subtitle: Text('IP: $ip'),
trailing: Text(status),
);
}
}

Ele recebe os dados prontos e apenas exibe. Se a tela de fora trocar o status e criar o CardServidor com outro valor, ele mostra o novo valor. O card em si não precisa guardar nada.



setState


O setState é o método usado para avisar ao Flutter que algum estado mudou e que a tela precisa ser reconstruída. No tópico anterior, vimos que o StatefulWidget guarda dados que podem mudar, como:

String status = 'Ativo';

Mas mudar essa variável sozinho não basta. Por exemplo:

status = 'Inativo';

Isso altera o valor na memória, mas o Flutter não sabe automaticamente que precisa redesenhar a tela. Para isso, usamos setState.