Flutter - Apresentando Layouts - I


Hoje veremos o conceito de Layouts no Flutter. (baseado na documentação oficial)

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

Se você não conhece o Flutter veja o meu artigo :  Flutter - Primeiros contatos e impressões

Layouts no Flutter

O núcleo do mecanismo de layout do Flutter são os widgets. No Flutter, quase tudo é um widget - até mesmo modelos de layout são widgets.

As imagens, os ícones e o texto que você vê em um aplicativo Flutter são todos widgets. Mas as coisas que você não vê também são widgets, como as linhas, colunas e grades que organizam, restringem e alinham os widgets visíveis.

Dessa forma você cria um layout compondo widgets para criar widgets mais complexos.

Na figura abaixo temos 3 ícones com uma label abaixo de cada um ícone:

A figura a seguir exibe o layout visual mostrando uma linha com 3 colunas onde cada coluna contém um ícone e uma label:

Abaixo temos um diagrama da árvore de widgets para esta interface do usuário:

Se você analisar com atenção a árvore de widgets acima pode se perguntar de onde vieram os contêineres que estão destacados na figura ?

Um Container é uma classe de widget que permite personalizar seu widget filho. Usamos um Contêiner quando desejamos adicionar preenchimento (padding), margens, bordas ou cor de fundo para nomear alguns de seus recursos.

Assim, neste exemplo cada widget de texto é colocado em um contêiner para adicionar margens. A linha inteira também é colocada em um contêiner para adicionar preenchimento ao redor da linha.

O resto da interface do usuário neste exemplo é controlado por propriedades.

A seguir vamos tratar dos widegts de layouts mais usados.

Configurando o ambiente

Eu estou usand o Flutter versão 1.2.1, e como editor de código estou usando o  VS Code com o plugin Flutter instalado.

Criando um projeto no Flutter

No Visual Studio Code tecle CTRL+ SHIFT+P para abrir a paleta de comandos e a seguir selecione a opção : Fluter:New Project



A seguir informe o nome do projeto : flutter_layouts1 e tecle ENTER

Na janela de diálogo a seguir selecione a pasta onde o projeto vai ser salvo e clique em :
Select a folder to create the project in

O Flutter vai criar um projeto padrão onde todo o código da aplicação vai estar no arquivo main.dart dentro da pasta lib do projeto.

A seguir substitua o código gerado no arquivo main.dart na pasta lib pelo código abaixo:

     import 'package:flutter/material.dart';
    // ponto de entrda da app 
    // o operador => é um atalho para  {} 
    // quando existe só uma linha de código
    void main() => runApp(MyApp());
    // o widget raiz da app
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text("Construindo layouts"),
            ),
            body: meuLayoutWidget(),
          ),
        );
      }
    }
    // substitua este método com o código do artigo
    Widget meuLayoutWidget() {
      return Text("Ola Flutter!");
    }

Observe o método meuLayoutWidget() no final. Isto é o que iremos substituir nos exemplos a seguir.

Para executar o projeto pressione F5 ou execute o comando flutter run -d all no terminal de comandos.

Widgets de layout básico (single child)

Primeiro, vamos dar uma olhada em alguns dos widgets de layout mais comuns e, depois, veremos como combiná-los em layouts mais complexos.

1- Padding

Pensar em padding como um widget é estranho quando você tem o primeiro contato com o Flutter. Pelo menos no mundo iOS e Android, o padding é um parâmetro. Mas no Flutter, se você quiser adicionar algum espaço extra ao redor de um widget, você o envolve em um widget Padding.

Vamos ver isso funcionando...

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

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

Por padrão ele vai incluir o código abaixo:

Widget meuLayoutWidget() {
      return Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text("Ola Flutter!"),
      );
    }

O parâmetro EdgeInsets é usado para especificar a quantidade de preenchimento. No exemplo usamos a opção all que indica que todos os lados (esquerda, superior, direita e inferior) devem ter preenchimento igual. Se você quiser que eles tenham valores diferentes, use a opção only e a seguir defina os valores para cada item:

const EdgeInsets.only({
    this.left = 0.0,
    this.top = 0.0,
    this.right = 0.0,
    this.bottom = 0.0
});

Para nosso caso após o Hot Reload ser efetuado veremos o resultado abaixo:

Observe que agora o texto se afastou das bordas e possui um padding (preenchimento) de 8,0 pixels lógicos em torno dele.

Fique a vontade para experimentar outros valores...

2 - Center

Para centralizar um widget, o conceito é o mesmo do Padding. Desta vez, vamos apenas envolver o widget com um widget Center. Você pode digitar ou usar a opção do menu de atalho:

Além de centralizar o texto, vamos adicionar um estilo ao widget Text para que o tamanho da fonte fique mais visível. Veja como ficou o código do método meuLayoutWidget:

     import 'package:flutter/material.dart';
    // ponto de entrda da app 
    // o operador => é um atalho para  {} 
    // quando existe só uma linha de código
    void main() => runApp(MyApp());
    // o widget raiz da app
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text("Construindo layouts"),
            ),
            body: meuLayoutWidget(),
          ),
        );
      }
    }
    // substitua este método com o código do artigo
    Widget meuLayoutWidget() {
      return Padding(
        padding: const EdgeInsets.all(12.0),
         child: Center(child: Text("Ola Flutter!", 
             style: TextStyle(fontSize: 30),
          )),
         );
    }

E se você quiser alinhar um widget em outro lugar?

Você pode usar o widget Align para isso. Você pode passar valores relativos de x e y ou usar os valores predefinidos. Aqui estão as opções. Os itens na mesma linha são equivalentes.

Alignment.topLeft

Alignment(-1.0, -1.0)

Alignment.topCenter Alignment(0.0, -1.0)
Alignment.topRight Alignment(1.0, -1.0)
Alignment.centerLeft Alignment(-1.0, 0.0)
Alignment.center Alignment(0.0, 0.0)
Alignment.centerRight Alignment(1.0, 0.0)
Alignment.bottomLeft Alignment(-1.0, 1.0)
Alignment.bottomCenter Alignment(0.0, 1.0)
Alignment.bottomRight Alignment(1.0, 1.0)

Perceba que outra maneira de centralizar algo é usar Alignment.center ou Alignment (0.0, 0.0). Na verdade, o widget Center é apenas um caso especial do widget Align.

A figura abaixo ilustrar melhor as posições :

Lembre-se de que esses números são relativos à largura e à altura do widget pai.

Abaixo um exemplo usando o alinhamento : Alignment.topCenter

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Construindo layouts"),
        ),
        body: meuLayoutWidget(),
      ),
    );
  }
}
Widget meuLayoutWidget() {
      return Align(
        alignment: Alignment.topCenter,
        child: Text(
          "Olá, Flutter",
          style: TextStyle(fontSize: 30),
        ),
      );
    }

3 - Container

A widget Container é uma combinação de vários widgets mais simples.

Além de ter Padding e Align embutidos, ele também tem um DecoratedBox (para cor de fundo, borda, etc.) e um ConstrainedBox (para restrições de tamanho).

Inclua o código abaixo no método meuLayoutWidget:

Widget meuLayoutWidget() {
      return Container(
        margin: EdgeInsets.all(30.0),
        padding: EdgeInsets.all(10.0),
        alignment: Alignment.topCenter,
        width: 200,
        height: 100,
        decoration: BoxDecoration(
          color: Colors.green,
          border: Border.all(),
        ),
        child: Text("Olá, Flutter",
                 style: TextStyle(fontSize: 30)),
      );
    }

Alterando os valores dos parâmetros podemos ajustá-los e ver como isso afeta a aparência dos widgets.

Aqui estamos centralizando o texto usando: Alignment.topCenter e desenhamos uma caixa com largura 200 e altura 100, definindo a cor verde e com todas as bordas.

Observe o parâmetro margin que significa o espaçamento fora da borda, enquanto o Padding é o espaçamento dentro da borda. Tecnicamente falando, porém, não existe margem em Flutter. 'Por baixo dos panos' é apenas outro widget de preenchimento que envolve o DecoratedBox.

Na próxima parte do artigo veremos os layouts básicos usando múltiplos filhos.

E a paz de Deus, que excede todo o entendimento, guardará os vossos corações e os vossos pensamentos em Cristo Jesus. Filipenses 4:7

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti