Flutter Widgets: StatelessWidget e StatefulWidget
Artigos Flutter Flutter Widgets: StatelessWidget e StatefulWidget
Por que eu devo ler este artigo:Criar UIs ou interfaces de usuário bonitas e que facilitem a experiência do usuário parece ser uma tarefa difícil. O framework Flutter torna essa tarefa mais fácil e intuitiva com a utilização dos Widgets, mesmo para alguém que não é um designer.
O Flutter foi concebido para criação de UI ou interfaces de usuário para aplicativos. Uma UI é construída em Flutter com base em Widgets, que são semelhantes aos Components utilizados em tecnologias como React.
Widgets com filhos
Método build
Exemplo de App com StatelessWidget
Exemplo de App com StatefulWidget
Um Widget gera uma parte da UI do aplicativo. Por exemplo: um texto, uma imagem ou um botão são criados a partir de um Widget.
Um aplicativo pode responder a eventos como um clique em um botão e alterar a visualização de seus componentes. Em Flutter para que isso aconteça é preciso mudar o estado de um Widget.
O Widget descreve como uma parte da UI deve ser visualizada, com base em sua configuração e estado atual. O estado é uma informação que é lida quando um Widget é construído. Essa informação pode ser como uma string ou um número, que quando muda também produz mudanças nas características de um Widget.
Com relação a mudança de estado os Widgets podem ser StatelessWidget e StatefulWidget:
StatelessWidget define Widgets que não mudam suas características com a mudança de estado. Um StatelessWidget não possui um estado que mude, pois é o Widget que mantém as mesmas características desde o início da execução do app.
StatefulWidget define Widgets que mudam suas características com a mudança de estado, ou seja, tem um estado mutável. Durante a execução do app, se a informação do estado mudar, isso será refletido no Widget.
Por exemplo, em um aplicativo ao clicar em um botão que é um StatefulWidget, um número é incrementado. O valor do número é uma informação ou estado que mudou e isso se refletiu no Widget Text que exibe o valor do número no aplicativo, conforme a Animação 1.
Animação 1. Exemplo de mudança de estado de um Widget com um contador
Nesse artigo vamos abordar apenas esses dois tipos de Widgets no contexto do estado.
Cada Widget pode ter um ou mais Widgets filhos. Criamos um com child, e para uma coleção de filhos usamos children. Veja um trecho de código onde declaramos um Widget filho com child, conforme a Listagem 1.
Listagem 1. Declaração de umWidget filho com child
Linha1: Declaração de um Widget Center
Linha 2: Declaração de um Widget filho com child. Esse Widget é um Text.
Agora temos outro trecho de código com a declaração de uma coleção de Widgets filhos com children, conforme a Listagem 2.
Listagem 2. Declaração de uma coleção de Widgets filhos com children
Linha 1: Declaração de um Widget Row
Linha 2: Declaração de uma coleção de Widgets filhos com children
Linhas 3 a 5: Widgets Icons compõem a coleção de Widgets filhos
Os Widgets são criados em um app através do método build, que contém um parâmetro BuildContext. Ele define a posição e características dos Widgets no layout do aplicativo.
No trecho de código a seguir temos o método build, conforme a Listagem 3.
Listagem 3. Trecho de código de um app utilizando o método build para criar os widgets
Linha 1: Método build que cria os Widgets no app
Linha 2: MaterialApp é o Widget principal
Linha 3: A página home do app tem como Widget principal Scaffold. Esse define um layout básico de acordo com o Material Design.
Linha 4: Widget AppBar, que será a barra superior do aplicativo, é um dos componentes do layout básico do Scaffold
Linha 5: propriedade title da AppBar para definir o título que será exibido na barra do app.
Vamos acompanhar alguns exemplos simples de apps feitos com Flutter.
Nos códigos de exemplo vamos utilizar a biblioteca flutter/material.dart para criar aplicativos de acordo com o Material Design, a linguagem de design criada pelo Google.
Nesse exemplo vamos usar o MaterialApp, que é um Widget de conveniência que agrupa outros widgets em um app que utiliza o Material Design.
Ao utilizar o MaterialApp podemos também usar o Widget Scaffold, que define um layout básico de acordo com o Material Design. Ele abrigará outros Widgets como AppBar, Container, Text e outros.
No código da Listagem 4 vamos criar um app com StatelessWidget, ou seja, os Widgets não sofrerão mudança durante a utilização do app.
void main() => runApp(const MeuApp());
const MeuApp({Key? key}) : super(key: key);
Listagem 4. Código básico para criação de um app com o Widget MaterialApp
Linha 1: Importa a biblioteca Material Design
Linha 3: Chamada ao método main() o ponto de entrada do app
Linha 5: Classe MeuApp
LInha 6: Construtor da classe MeuApp
Linha 7: @override indica que vamos sobrescrever o método build
Linha 8: Método build do Widget
Linha 9: Retorna o Widget MaterialApp
Linha 10: definindo uma rota home para um Widget Scaffold
Linha 11: Widget AppBar para criar a barra do aplicativo
Linha 12: Criando um título para a barra do aplicativo com o Widget Text
Podemos ver o app com o Widget MaterialApp em execução na Figura 1.
Figura 1. App com StatelessWidget em execução
Agora um exemplo de app utilzando MaterialApp e StatefulWidgets que são Widgets que mudam sua visualização de acordo com seu estado. Será um aplicativo bem simples com uma AppBar, um Container, um Center, um Text e um ElevatedButton. O Text vai mudar a medida que clicarmos no ElevatedButton.
O código para criar esse app pode ser visto na Listagem 5.
home: MyButton(),
)); // MaterialApp
return MyButtonState();
List<String> strings = ['Flutter','é','legal','e','incrível.'];
String displayedString = "Olá Mundo!";
title: const Text("Exemplo com StatefulWidget"),
Text(displayedString, style: const TextStyle(fontSize: 40.0)),
const Padding(padding: EdgeInsets.all(10.0)),
"clique aqui",
primary: Colors.red
), // ElevatedButton
Listagem 5. Código de um App Flutter com MaterialApp e StatefulWidget
Linha 1: Importa a biblioteca flutter/material.dart para aplicar o Material Design ao app
Linha 3: Método main() é o ponto de entrada do aplicativo
Linha 4: O método runApp chama o MateialApp como o Widget principal
Linha 5: definimos a rota home para o Widget MyButton
Linha 9: declaração do Widget MyButton que é um StatefulWidget
Linha 12 e 13: sobrecarga do método createState
Linha 14: O método createState retorna a classe MyButtonState
Linha 18: classe MyButtonState que extende a classe State para o objeto MyButton
Linha 19: variável counter que irá contar os cliques no botão
Linha 20: Declaração de uma lista de strings
Linha 21: variável do tipo String displayedString
Linha 23: método onPressOfButton que captura o clique do botão
Linha 24: setState define o estado do botão
Linha 25: ao clique do botão a variável displayedString recebe o elemento da lista strings no índice com valor igual ao da variável counter
Linha 26: A variável counter é atualizada de acordo com a avaliação da expressão: counter < 4. Se a expressão for verdadeira o valor da variável counter será incrementado em 1 e se for falsa o valor da variável counter será 0
Linhas 30 e 31: sobrecarga do método build que renderiza os Widgets no app.
Linha 32: retornamos um Widget Scaffold que é um repositório para outros Widgets
Linha 33: Widget AppBar para criar a barra superior do app
Linha 34: Propriedade título do AppBar
Linha 35: Definida a propriedade backgroundColor ou cor de fundo para verde
Linha 37: corpo do Scaffold recebe um Widget Center para centralizar conteúdo
Linha 38: Widget Column que cria um Layout vertical para alinhar outros Widgets
Linha 39: propriedade mainAxisAlignment do Widget Column definindo o alinhamento como central
Linha 40: Declaração de children que é uma coleção de Widgets filhos
Linha 41: Widget Text que exibe o valor da variável displayedString que muda de acordo com o clique do botão
Linha 42: Widget Padding que cria um espaço em branco antes do próximo Widget filho
Linha 43: Widget ElevatedButton que é um botão que dá uma sensação de volume.
Linha 44: Widget Text filho de ElevatedButton que é exibido como texto do botão
Linha 45: propriedade texto do Widget Text do ElevatedButton
Linha 46: propriedade estilo do Widget Text do ElevatedButton que está definindo a cor do texto como branca
Linha 48: propriedade de estilo para o Widget ElevatedButton
Linha 49: Propriedade para definir a cor de fundo do Widget
Linha 51: evento onPressed que está levando ao método onPressOfButton quando o botão for clicado
O método createState() pertence a classe StatefulWidget. As classes que herdarem dela devem sobrescrever esse método para retornar a instância da subclasse recém-criada. Ele basicamente cria o estado mutável para o Widget.
O método setState() é chamado quando o estado interno do objeto é alterado. Ele define as propriedades no objeto de estado e aciona atualizações na interface. Com isso, quando esse método for executado, o Widget será reconstruído com os valores atualizados.
Podemos ver o app em execução na Animação 2.
Animação 1. App criado com Flutter usando StatefulWidget que responde a mudança de estado
O objetivo desse artigo não é ser uma descrição de todos Widgets do Flutter mas explicar a utilização dos Widgets com alguns exemplos mais básicos. A medida que avançar nos estudos do framework você irá conhecer outros Widgets.