Mobile

26 abr, 2019

Flutter – Parte 01: apresentando widgets

100 visualizações
Publicidade

Hoje vou apresentar o conceito de widgets no Flutter.

O Flutter é um SDK de aplicativo móvel da Google, que ajuda a criar aplicativos móveis modernos para iOS e Android usando uma  – quase – única base de código.

Se você não conhece o Flutter, confira meu artigo:

No Flutter, tudo são widgets. Assim, os Widgets são as partes da sua interface de usuário. Um Text é um widget; Buttons são widgets; caixas de seleção são widgets; imagens são widgets, e a lista continua.

Na verdade, tudo na interface do usuário é um widget – até mesmo o aplicativo em si!

Você pode pensar em um Widget como uma View do Android ou UIView do iOS, mas uma forma mais precisa de pensar é ver um widget como um template ou modelo, e que o Flutter usa esses templates/modelos para criar os elementos de visualização debaixo dos panos e para renderizá-los na tela do dispositivo.

Quando você entende que os widgets são quase tudo que afeta a aparência e o comportamento da interface, faz sentido que haja muito mais widgets do que apenas elementos estruturais, como botões, texto e imagens. Por exemplo: o Padding é um widget; Columns são widgets; Styles são widgets e até detetores de gestos são widgets.

Árvores de widgets

Os widgets são organizados em uma árvore de widgets numa hierarquia pai e filho. Toda a árvore de widgets é o que forma o layout que você vê na tela.

Por exemplo, aqui está a árvore de widgets para o aplicativo de demonstração padrão, quando você inicia um novo projeto.

Os widgets visíveis são marcados com linhas vermelhas (os outros widgets nessa árvore são usados para layout e adição de funcionalidade).

Nota: você pode visualizar a árvore de widgets de qualquer projeto usando a ferramenta Flutter Inspector.

Tipos de widgets

Os Widgets são imutáveis. Ou seja, eles não podem ser alterados. Quaisquer propriedades que eles contêm são finais, e só podem ser definidas quando o widget for inicializado.

Isso os mantém leves, de modo que é barato recriá-los quando a árvore de widgets for alterada.

Existem dois tipos de widgets:

  • 1. Sem estado ou StatelessWidget
  • 2. Com estado ou StatefulWidget

1. Widgets sem estado são widgets que não armazenam nenhum estado. Ou seja, eles não armazenam valores que podem mudar.

Por exemplo: um ícone é sem estado – você define a imagem do ícone quando a cria e depois não muda mais. Um widget de texto também é sem estado.

Você pode dizer: “Mas espere, você pode alterar o valor do texto”. É verdade, mas se você quiser alterar o valor do texto, basta criar um novo widget inteiro com o novo texto. O widget Text não armazena uma propriedade de texto que pode ser alterada.

2. O segundo tipo de widget é chamado de widget com estado. Isso significa que ele pode acompanhar as alterações e atualizar a interface do usuário com base nessas alterações.

Agora você pode dizer: “Mas você disse que os widgets são imutáveis! Como eles podem acompanhar as mudanças?”.

Sim, o próprio widget stateful é imutável, mas ele cria um objeto State que controla as alterações. Quando os valores no objeto State mudam, ele cria um novo widget inteiro com os valores atualizados. Assim, um widget leve (blueprint) é recriado, mas o estado persiste entre as alterações.

Um widget com estado é útil para algo como uma caixa de seleção. Quando um usuário clica nela, o estado (check) da verificação é atualizado.

Outro exemplo é um widget Image. O recurso de imagem pode não estar disponível quando o widget for criado (como se estivesse sendo baixado). Portanto, um widget sem estado não é uma opção – quando a imagem estiver disponível, ela pode ser definida atualizando o estado.

Para saber mais, veja este canal no YouTube:

Trabalhando com widgets

Agora veremos como trabalhar com os widgets mais comuns do Flutter. Vamos criar um novo projeto Flutter no VS Code, chamado “flutter_widgets_1“.

Abra o arquivo main.dart da pasta lib e delete todo o texto neste arquivo, substituindo pelo código abaixo:

Se você recarregar seu aplicativo agora, deve ver uma tela em branco.

A função main() é o ponto de partida para todos os aplicativos Flutter. Neste momento, nosso aplicativo não faz nada, mas em cada um dos exemplos abaixo, vamos testar um widget Flutter diferente.

Widget Container

Começaremos usando o widget Container, ele é um suporte para outros widgets. Mas não vamos colocar mais nada, para começar. Apenas brincaremos com sua propriedade color.

Substitua todo o código em main.dart pelo seguinte:


    // A importação deste pacote nós da acesso aos widgets dart
    // bem como aos Widgets Material Theme
    import 'package:flutter/material.dart';
    // o método main() é o ponto de entrada da sua aplicação
    void main() {
      // chamando este método você executa sua aplicação
      runApp(
        // runApp() usa qualquer widget como um argumento.
        // Este widget será usado como o layout.
        // Vamos usar o Container
        Container(
          color: Colors.blue, // <-- altere aqui
        ),
      );
    }

O widget Container combina widgets comuns de pintura, posicionamento e dimensionamento. Como o Container combina vários outros widgets, cada um com seu próprio comportamento de layout, o comportamento do layout do Container pode ser um pouco complicado.

No código, você percebe que são usadas vírgulas para formatar linhas; se você quiser remover as vírgulas, até pode, mas o texto seria escrito em uma única linha quando há formatação automática.

Na figura ao lado você vê o resultado da execução pressionando F5 (ou digitando flutter run -d all).

Se você alterar o valor da propriedade Colors para outra cor, como red, green, etc, e tentar dar um Hot Reload, nada vai acontecer.

Para ver o efeito da mudança, você tem que reiniciar a aplicação, e isso é devido ao fato de não estarmos usando um widget com estado, pois estamos executando o código dentro do método runApp().

Widget Text

O Widget Text é um candidato a estar presente no seu aplicativo, portanto, é um widget muito

Agora criaremos outro projeto no VS Code chamado “flutter_widget_2“.

No arquivo main.dart, substitua o código original pelo código abaixo:

   import 'package:flutter/material.dart';
    void main() {
      // O método runApp() inicializa o layouta da app
      // MyApp() é um widget que será a raiz da nossa aplicação
      runApp(MyApp());
    }
    // o widget raiz
    class MyApp extends StatelessWidget {
      // O método build reconstrói a árvore de widegts se houver mudanças
      // e permite o hot reload 
      @override
      Widget build(BuildContext context) {
        // Agora ao ínves de um Container estamos usando o widget MaterialApp 
        // o qual é configurado para dar à nossa app um tema Material
        return MaterialApp(
          // O widget Scaffold define o layouta da home 
          home: Scaffold(
            // Vamos passar um widget AppBar widget para a propriedade appBar do Scaffold
            appBar: AppBar(
              // A prop. AppBar usa um widget Text widget para a sua prop. title
              title: Text("Explorando Widgets"),
            ),
            // A prop. body do widget Scaffold widget é o conteúdo principal da tela
            // Ao inves de usar diretamente a widget nós vamos definir a widgter em outro
            // método para facilitar o tratamento
            body: myWidget(),
          ),
        );
      }
    }
    // Aqui é onde vamos tratar a widget Text
    Widget myWidget() {
      return Text(
        "Olá, Mundo",
      );
    }

Neste código estamos usando o widget MaterialApp que faz com que o aplicativo pareça mais bonito e simplifique o resto do código.

O Widget MaterialApp que encapsula um grupo de widgets que devem ser usados ​​no Material Design.

Além disso, o método build() permite usar o hot reload para atualizar a aplicação após as alterações.

Preste atenção no método myWidget() na parte inferior. Vamos usá-lo para retornar o widget Text, com o qual estamos tratando aqui.

Executando o projeto pressionando F5, você verá o resultado exibido na figura 1:

Figura 1
Figura 2

Agora, se você alterar o texto o hot reload, vai exibir as alterações feitas imediatamente, conforme a figura 2, acima.

Vamos aumentar o tamanho da fonte do texto adicionando um widget TextStyle à propriedade de estilo do texto.

  ...
    // Aqui é onde vamos tratar a widget Text
    Widget myWidget() {
      return Text(
        "Olá, Mundo... ",
        style: TextStyle(
          fontSize: 30.0, 
        ),
      );
    }

Perceba a alteração se refletindo na aplicação.

Assim, existem muitas outras alterações que você pode fazer com o widget TextStyle, como: cor, fonte, sombras e espaçamento – para citar algumas.

Se você quiser adicionar um preenchimento ou padding, não altere uma propriedade. Em vez disso, você pode envolver o widget Text com um widget Padding.

No Flutter, muitas tarefas relacionadas ao layout usam widgets ao invés de definir propriedades. Lembre-se: um widget é um template que afeta a aparência da interface do usuário.

Vamos adicionar o widegt Padding envolvendo o widget Text no método myWidget:

No Visual Studio Code basta selecionar o widget Text, e a seguir clicar no ícone e selecionar a opção Add padding:

Vamos alterar o código da widget myWidget conforme abaixo:

// Aqui é onde vamos tratar a widget Text
Widget myWidget() {
      return Padding(
        // Define o padding usando o widget EdgeInsets.
        // O valor 16.0 significa 16 pixels logicos. Esta é
        // uma resolução independente.
        padding: EdgeInsets.all(16.0),
        // Quando envolver um widget com outro widget,
        // você usa a propriedade child do widget pai
        child: Text(
          "Olá,Mundo Flutter!",
        ),
      );
    }

Perceba o preenchimento com espaços na exibição do texto.

Na próxima parte do artigo vamos continuar apresentando outros widgets importantes.