Você está na página 1de 19

Open in app Get started

Published in flutter-angola

Márcio Quimbundo Follow

Apr 4, 2019 · 10 min read

Save

Introdução ao Flutter: O Básico

Eu tenho ouvido falar sobre o quão incrível Flutter é, então, eu decidi experimentá-lo
para aprender algo novo.

Comecei com o Flutter fazendo um curso no Udacity, depois lendo a documentação


oficial, e então comecei a codificar em projetos reais. Foi uma boa experiência. Os
aplicativos estavam a rodar e tudo que foi escrito não era difícil de entender.

No entanto, o processo não foi fácil assim — alguns detalhes não foram explicados
nesses recursos que me foi disponibilizado no princípio. Além disso, como tudo era
novo para mim (a própria plataforma, linguagem de programação, abordagens e até
mesmo o desenvolvimento de aplicativos móveis), a falta desses detalhes era doloroso.
300 5
Toda vez que algo não funcionava, eu não sabia o que pesquisar no Google: Dart,
Flutter, Window, Screen, Route, Widget?
Open in app Get started

Eu decidi que ler a documentação sobre Dart, Flutter e todos os seus widgets não seria
uma boa ideia, já que seria muito demorado. Além disso, eu não tinha muito tempo,
pois o objetivo era conhecer a novidade e não me tornar um especialista na área. Eu
pensei que naquele momento seria incrível se houvesse um pequeno guia sobre Flutter,
que descreveria todos os conceitos necessários para entender o framework e ser capaz
de escrever aplicativos simples, e depois ir até ao mais complexo.

Sobre o Guia
A maioria dos artigos sobre flutter é bem direta. O problema é que eles exigem que você
conheça algumas coisas básicas, e essas pequenas coisas não são descritas em artigos
que supostamente lhe dariam o conhecimento básico.

Nestas séries, tentarei evitar esse problema. Começaremos do zero e criaremos


aplicativos para resolver todas as etapas que fizermos. Durante esta série, utilizaremos
todos os widgets básicos, projetaremos uma interface exclusiva, interagiremos com
módulos nativos e criaremos nosso aplicativo para as plataformas iOS e Android.

Vou resumir, para economizar o vosso tempo. Para os mais curiosos, colocarei links
úteis em torno de alguns textos.

Sobre a Plataforma
O Flutter é um SDK open source para desenvolvimento de aplicativos móveis criado
pelo Google. Ele é utilizado para desenvolver aplicativos para Android e iOS.

O Flutter é muito novo, mas uma plataforma promissora, que atraiu a atenção de
grandes empresas que já lançaram seus aplicativos. É interessante por causa de sua
simplicidade em comparação ao desenvolvimento de aplicações Web e por causa de sua
velocidade em comparação com aplicativos nativos.

Alta performance e produtividade no Flutter são obtidos utilizando várias técnicas:

Ao contrário de muitas outras plataformas móveis populares, o Flutter não utiliza


JavaScript de nenhuma maneira. Dart é a linguagem de programação. Ele compila
para código binário, e é por isso que ele é executado com o desempenho nativo de
Objective-C, Swift, Java ou Kotlin.

Flutter não utiliza componentes de UI nativos. Isso pode parecer estranho no


começo No entanto como os componentes são implementados no próprio Flutter
começo. No entanto, como os componentes são implementados no próprio Flutter,
não há camada de comunicação entre a view e seu código. Devido
Open in appa isso,
Getas
started

aplicações atingem a melhor velocidade. Então, botões, texto, elementos de mídia,


backgrounds são todos desenhados pelo mecanismo de gráficos do Flutter. Como
um aparte, deve ser mencionado que o pacote do aplicativo Flutter “Olá, Mundo” é
bem pequeno: iOS ≈ 2.5Mb e Android ≈ 4Mb.

O Flutter utiliza uma abordagem declarativa, inspirada no framework web React,


para construir sua UI baseada em widgets (chamados “componentes” no mundo
web). Para obter mais de widgets, eles são renderizados apenas quando necessário,
geralmente quando seu estado foi alterado (assim como o Virtual DOM faz para nós
na WEB).

Além de todos os itens acima, o framework integrou o Hot-reload, típico da web,


mas ainda ausente em plataformas nativas. Isso permite que a estrutura Flutter
reconstrua automaticamente a árvore(tree) de widgets, permitindo que você
visualize rapidamente os efeitos de suas alterações e permite trabalhares com o
designer ao pé de ti porque não precisas mais de 5 segundos para ver a cor do botão
que alteraste ou qualquer outra alteração.

Há um excelente artigo sobre o uso prático desses recursos de um desenvolvedor


Android que recriou seu aplicativo de Java para Dart e compartilhou suas impressões.

Eu queria compartilhar com vocês alguns números do artigo dele.

Java (antes): Número de arquivos = 179 e linhas de código 12.176

Dart (depois): Número de arquivos = 31 e linhas de código 1.735.

Você pode ler mais sobre os detalhes técnicos da plataforma ou ver exemplos de
aplicativos.

Sobre o Dart
O Dart é uma linguagem de programação que utilizaremos para desenvolver nosso
aplicativo no Flutter. Aprender é bem fácil se você tiver experiência com Java ou
JavaScript. Você vai conseguir rapidamente.

Para quem quiser ver o guia e resumo sobre a linguagem Dart escrita pela equipa que
mantém o Dart pode clicar AQUI.

Configuração inicial
Este tópico, assim como o da linguagem Dart, está muito bem abordado no guia oficial.
Open in app Get started
Por isso, não vou descreve-la aqui.
Percorra por este pequeno guia de configuração, escolhendo o seu sistema operativo e
seguindo-o passo a passo. Além disso, configure seu editor preferido para trabalhar
com o Dart e o Flutter (geralmente requer 2 plugins diferentes). Execute seu aplicativo
para garantir que você esteja pronto para continuar.

Projeto demo que é gerado ao criar a primeira aplicação no Flutter

Estrutura do Projeto
Primeiro, vamos ver o que está no projeto gerado pelo framework Flutter:

lib/ — todo o código do projeto estará aqui.

pubspec.yml — armazena uma lista de pacotes necessários para executar o


aplicativo, assim como o package.json faz nas aplicações web. Você deve se lembrar
que nos projetos Flutter você não pode usar o pub(gerenciador de pacotes do dart)
diretamente, mas, em vez disso, você utilizará o comando Flutter: flutter pub get

<package_name> ou flutter packages get

test/ — pasta responsável por armazenar os testes automatizados do teu projeto.


Quanto mais recursos seu aplicativo tiver, mais difícil será testar manualmente. Os
testes automatizados ajudam a garantir que o seu aplicativo funcione corretamente
antes de publicá-lo, mantendo o recurso e a velocidade de correção do bug.

ios/ & android/ — o código específico de cada plataforma, incluindo ícones e


ios/ & android/ o código específico de cada plataforma, incluindo ícones e
configurações de aplicativos nos quais você define as permissões necessárias
Open in app para o
Get started

seu aplicativo (como acesso à localização, Bluetooth).

Por enquanto, já não precisamos saber mais sobre os arquivos dentro pasta. Vamos
abrir a pasta lib / onde main.dart está esperando por nós. Como você pode imaginar,
esse é o ponto de entrada do nosso aplicativo. Assim como na linguagem C (ou na
maioria), o aplicativo será executado chamando a função main () que é a função
principal do projeto.

Sobre Widgets (Olá mundo está aqui)


Em Flutter tudo é construído em Widgets. Elementos UI(interface do utilizador),
estilos, temas e até mesmo os estados são gerenciados em widgets específicos. Vamos
começar com um pequeno aplicativo.

Substitua o código de main.dart com o dado abaixo, leia os comentários e execute o


aplicativo.

1 import 'package:flutter/widgets.dart'; //importação básica dos widgets


2
3 //Quando o Dart está executando o aplicativo, primeiramente ele chama a função main ()
4 main() => runApp( //a função runApp() lança a aplicação flutter no dispositivo
5 Text( // isto é um widget, ela renderiza o texto inserido
6 'Olá, Mundo!!!',//o primeiro argumento é um texto que precisa ser renderizado
7 textDirection: TextDirection.ltr, //aqui a direção do texto "da esquerda para direita"
8 ),
9 );

main dart hosted with ❤ by GitHub view raw


runApp(…) tem apenas um argumento widget. O widget se tornará o widget raiz para
todo o aplicativo. Atenção que a mudança deste widget raiz não pode ser feita pelo Hot-
reload, então você terá que reiniciar o aplicativo para ver as alterações.

Text(…) exibe uma string de texto com estilo único. A seqüência pode quebrar várias
linhas ou todas podem ser exibidas na mesma linha, dependendo das restrições de
layout.

Seu aplicativo já está em execução? Yeah! “Olá, Mundo!” Está na tela agora. Certo? Eh,
algo deu errado.
Open in app Get started

Conteúdo quase sobreposto pela barra de status do telefone

O texto está quase sobreposto pela barra de status do telefone. Podemos utilizar toda a
tela do nosso aplicativo, e imprimimos nosso conteúdo no topo do mesmo, onde as
informações do sistema também são processadas.

Vamos tentar mudar nosso conteúdo:

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Center( // O widget que alinha o conteúdo no centro
5 child: Text(
6 'Olá, Mundo!!!',
7 textDirection: TextDirection.ltr,
8 ),
9 ),
10 );

main.dart
hosted with ❤ by GitHub view raw
Evitar sobreposição de conteúdo

Center(…) é o widget que alinha outro widget dado na propriedade filho(child) no


centro de si mesmo. Muitas vezes, você verá as propriedades filho(child) e
filhos(children) nos aplicativos Flutter, pois quase todos os widgets estão os utilizando
quando precisam de um ou vários widgets para serem renderizados dentro deles.

Uma conjunto de widgets no Flutter é utilizado para representar uma interface, alterar
sua aparência e compartilhar dados. Por exemplo, Directionality(…) define a direção
p p p , y( ) ç
Open in app Get started

do texto para todos os widgets aninhados (então, não é necessário especificá-lo para
cada Text(…) todas as vezes).

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Directionality(
5 textDirection: TextDirection.ltr,
6 child: Center(
7 child: Text(
8 'Olá, Mundo!!!',
9 ),
10 ),
11 ),
12 );

main.dart
hosted with ❤ by GitHub view raw
Utilizando o widget Directionality no Flutter

Vamos dar uma olhada em um widget muito importante e alterar o design do nosso
aplicativo:

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Directionality(
5 textDirection: TextDirection.ltr,
6 child: Container( // o novo widget! é o <div> no mundo do Flutter
7 //para o [Container], a propriedade[color] significa a cor do fundo(background-
8 color: Color(0xFF444444),
9 child: Center(
10 child: Text(
11 'Olá, Mundo!!!',
12 style: TextStyle( //utilizamos o widget[TextStyle] para customizar o widget
13 color: Color(0xFFFD620A),//configura a cor do texto
14 fontSize: 32.0, //configura o tamanho do texto
15 ),
16 ),
17 ),
18 ),
19 ),
20 );
main.dart
hosted with ❤ by GitHub view raw
Open in app Get started
Utilizando Container no Flutter

Aplicação “Olá, mundo” feito com Flutter

Existem várias opções sobre como utilizar o widget Color (…). Nós utilizamos o widget
com o valor dado a ele utilizando a notação hexadecimal. Isso parece quase o mesmo
quando definimos cores HEX na Web, mas aqui temos dois símbolos adicionais no
começo. Este é um número que representa a transparência em que 0x00 é totalmente
transparente e 0xFF não é assim tão transparente.
Open in app Get started

TextStyle(…) é mais interessante. Você pode usá-lo para definir uma cor, tamanho e
peso da fonte, espaçamento entre linhas, texto sublinhado etc.

A aplicação Flutter está completa! Você pode ler mais e aprender a publicá-lo na loja de
aplicativos relevante AppStore ou PlayStore. Se não for o suficiente para você, eu
abordei mais alguns tópicos abaixo.

Sobre Stateless Widgets (Widget sem estado)


Agora que sabemos o quão fácil é utilizar widgets. O próximo passo lógico seria criar
nossos widgets. Eu mencionei antes que há dois tipos de widgets (na verdade, mais,
mas não vamos complicá-lo por enquanto). Existem widgets sem estado(stateless) e
com estado(stateful).

Estávamos a utilizar widgets sem estado(stateless widgets) nos exemplos anteriores.


“Sem estado”(Stateless) não significa que eles não tenham estado em tudo. Widgets
são classes Dart, que podem ser declaradas com propriedades. Mas alterar essas
propriedades em um widget sem estado(stateless widgets) não afetará o que já foi
processado. A atualização de propriedades de um widget com estado irá disparar
ganchos do ciclo de vida e renderizar seu conteúdo utilizando o novo estado.
Começaremos com widgets sem estado(stateless widgets), pois eles parecem ser um
pouco mais fáceis.

Para criar um, precisamos:

1. Um nome bonito para a nova classe.

2. Estender(extend) a nossa classe de StatelessWidget.

3. Implementar o método build(), que receberá um argumento do tipo BuildContext


e retornar o tipo Widget.

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Directionality(
5 textDirection: TextDirection.ltr,
6 child: Center(
7 child: WidgetSemEstado(),
8 ),
9 ),
10 ); Open in app Get started
11
12 class WidgetSemEstado extends StatelessWidget {
13 //a notação @override é preciso para otimização, utilizando-a
14 //dizemos que não precisamos do mesmo método da classe pai
15 //então o compilador pode soltá-lo
16 @override
17 Widget build(BuildContext context) {
18 return Text(
19 'Olá, Mundo!!!',
20 );
21 }
22 }

main.dart
hosted with ❤ by GitHub view raw
exemplo de StatelessWidget no Flutter

Exemplo de widget com um argumento:

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Directionality(
5 textDirection: TextDirection.ltr,
6 child: Center(
7 child: WidgetSemEstado("Mundo!!!"),
8 ),
9 ),
10 );
11
12 class WidgetSemEstado extends StatelessWidget {
13 //todas as propriedades do StatelessWidget devem ser declaradas com as palavras chave
14 //const é utilizado para constantes em tempo de compilação
15 //final só podem ser definidas apenas uma vez
16
17 final String nome;//propriedade da class
18 WidgetSemEstado(this.nome);// construtora da class
19
20 @override
21 Widget build(BuildContext context) {
22 return Text(
23 'Olá, $nome',
24 );
25 }
26 }
main dart hosted with ❤ by GitHub view raw
Open in app
exemplo de um StatelessWidget com argumento Get started

Sobre Hot Reload


Observe que, depois de movermos o conteúdo do nosso aplicativo para o widget
separado, o aplicativo será renderizado novamente sempre que salvarmos nossas
alterações. Isso é hot-reload em ação.

Também é crucial entender que, enquanto você está trabalhando no modo de


desenvolvimento com o hot-reload ativado, o aplicativo funcionará muito mais
lentamente do que no modo de liberação(release).

Sobre GestureDetector

widget GestureDetector respondendo ao clique do botão azul


Open in app Get started

Vamos criar um StatefulWidget(widget com estado) na próxima seção. Para ter certeza
de que será interessante, precisamos mudar o estado do widget, certo? Utilizaremos o
GestureDetector (…) para essa finalidade. Este widget não renderiza nada na tela, mas
cuida da interação do utilizador com a tela e chama as funções relacionadas a ele.

O exemplo abaixo cria um botão azul no centro da tela e, quando esse botão é
pressionado, o texto é impresso no terminal:

1 import 'package:flutter/widgets.dart';
2
3 main() => runApp(
4 Directionality(
5 textDirection: TextDirection.ltr,
6 child: Container(color: Color(0xFFFFFFFF), child: WidgetSemEstado()),
7 ),
8 );
9
10 class WidgetSemEstado extends StatelessWidget {
11 @override
12 Widget build(BuildContext context) {
13 return Center(
14 child: GestureDetector( // um widget normal
15 onTap: () { // uma das propriedades do [GestureDetector]
16 //esta função será chamada quando o filho(child) do widget for pressionado
17 print("Botão clicado");
18 },
19 child: Container( //o container vai representar o nosso botão
20 decoration: BoxDecoration( //é dessa forma que estilizamos o [Container]
21 shape: BoxShape.circle, // muda a sua forma de rectangulo para um circulo
22 color: Color(0xFF17A2B8), //e o pinta de azul
23 ),
24 width: 80.0,
25 height: 80.0,
26 ),
27 ),
28 );
29 }
30 }

main dart hosted with ❤ by GitHub view raw


utilizando o widget GestureDetector pra responder ao clique do botão

Pressione o botão e a mensagem será impressa no terminal. Pressione novamente e o


texto aparecerá novamente.
Open in app Get started

Sobre Stateful Widgets (Widget com estado)


StatefulWidget são simples. Sim, tão simples quanto o StatelessWidget! No entanto,
existe uma extra. Eles não existem por si mesmos. Eles exigem uma classe extra para
armazenar o estado do widget. Além disso, a parte visual do widget se torna seu estado.

Aqui está um exemplo de uma class StatefulWidget:

1 // ...
2
3
4 class Contador extends StatefulWidget {
5 //o estado não está armazenado no widget, mas dentro de uma classe especifica
6 //que é criado pelo createState()
7 @override
8 State<Contador> createState() => _ContadorEstado();
9 //o resultado da função é um objecto, que deve ser
10 //do tipo State<Contador> (onde Contador é o nome do nosso Widget)
11 }

main.dart
hosted with ❤ by GitHub view raw

Criamos um widget “vazio” que implementa apenas um método e não contém


representação de estado ou de interface do utilizador(UI). Forçando essa separação, o
Flutter busca maior otimização do aplicativo.

O estado também não é complicado. De fato, é exatamente como nosso


StatelessWidget. A principal diferença é sua classe pai.

1 //...
2
3
4 class _ContadorEstado extends State<Contador> {
5 //finalmente, podemos declarar variaveis dinamicas dentro das nossas classes,
6 //para armazenar o estados dos nossos widgets
7
8 //nesse caso, armazenaremos o número
9 int contador = 0;
10
11 //o resto é super simples, apenas implementamos o familiar para nós o metodo build()
12 // da mesma forma que fizemos na nossa [StatelessWidget]
13 @override
14 Widget build(BuildContext context) {
15 //quase nada mudou desde o último exemplo.
Open in app Get started
16 //adicionamos comentários para realçar a diferença
17 return Center(
18 child: GestureDetector(
19 onTap: () {
20 //uma vez que o botão é pressionado, aumentaremos o valor da variavel [contad
21 setState((){
22 //o uso do setState() é necessário para acionar ganchos do ciclo de vida
23 //então o widget saberá quando ela deve ser atualizado
24 ++contador;
25 });
26 },
27 child: Container(
28 decoration: BoxDecoration(
29 shape: BoxShape.circle,
30 color: Color(0xFF17A2B8),
31 ),
32 width: 80.0,
33 height: 80.0,
34 child: Center(
35 child: Text('$contador', style: TextStyle(fontSize: 30.0),),
36 ),
37 ),
38 ),
39 );
40 }
41 }

declaração da class State do widget


Aplicação contadora construída utilizando widgets em Flutter
Open in app Get started

Eu nomeei nossa classe State começando com um sublinhado. Na linguagem Dart,


todos os nomes que começam com um sublinhado são privados (ao contrário do
JavaScript ou do Python, eles estão realmente indisponíveis fora da biblioteca).
Normalmente, não precisamos expor nossas classes States fora da biblioteca, portanto,
é uma boa prática mantê-las privadas.

Nós criamos um aplicativo fantástico. Ótimo resultado!

Antes de terminarmos esta parte, vamos dar uma olhada em alguns widgets mais
interessantes. Desta vez, escreveremos mais códigos de uma vez e não explicarei todas
as linhas. Você provavelmente já pode entender a maior parte do código:

1 import 'package:flutter/widgets.dart';
2
3 main()=>runApp(App());
4
5 class App extends StatelessWidget {
6 @override
7 Widget build(BuildContext context) {
8 return Directionality(
9 textDirection: TextDirection.ltr,
10 child: Container(
11 padding: EdgeInsets.symmetric(vertical: 60.0, horizontal: 80.0),
12 color: Color(0xFFFFFFFF),
13 child: Conteudo(),
14 ),
15 );
16 }
17 }
18
19 class Conteudo extends StatelessWidget {
20 @override
21 Widget build(BuildContext context) {
22 return Column(
23 children: <Widget>[
24 Contador('Manchester United'),
25 Contador('Juventus'),
26 ],
27 );
28 }
29 }
30
31 l C t d t d St t f lWid t {
31 class Contador extends StatefulWidget {
32 final String _nome; Open in app Get started
33 Contador(this._nome);
34
35 @override
36 State<Contador> createState()=>_ContadorEstado();
37 }
38
39 class _ContadorEstado extends State<Contador> {
40 int conta = 0;
41
42 @override
43 Widget build(BuildContext context) {
44 return Container(
45 margin: EdgeInsets.only(bottom: 10.0),
46 padding: EdgeInsets.all(4.0),
47 decoration: BoxDecoration(
48 border: Border.all(color: Color(0xFFFD6A02)),
49 borderRadius: BorderRadius.circular(4.0),
50 ),
51 child: Row(
52 mainAxisAlignment: MainAxisAlignment.spaceBetween,
53 children: <Widget>[
54 // [widget] é a propriedade que a classe estao armazena
55 // a instancia do [StatefulWidget] ([Contador] no nosso caso)
56 _ContadorRotulo(widget._nome),
57 _ContadorBotao(
58 conta,
59 onPressed: () {
60 setState((){
61 ++conta;
62 });
63 }
64 )
65 ],
66 ),
67 );
68 }
69 }
70
71 class _ContadorRotulo extends StatelessWidget {
72 static const textStyle = TextStyle(
73 color: Color(0xFF000000),
74 fontSize: 26.0,
75 );
76
77 final String _rotulo;
78 _ContadorRotulo(this._rotulo);
79
80 @override Open in app Get started
81 Widget build(BuildContext context) {
82 return Text(
83 _rotulo,
84 style: _ContadorRotulo.textStyle,
85 );
86 }
87 }
88
89 class _ContadorBotao extends StatelessWidget {
90 final conta;
91 final onPressed;
92 _ContadorBotao(this.conta, {@required this.onPressed});
93
94 @override
95 Widget build(BuildContext context) {
96 return GestureDetector(
97 onTap: onPressed,
98 child: Container(
99 padding: EdgeInsets.symmetric(horizontal: 6.0),
100 decoration: BoxDecoration(
101 color: Color(0xFFFD6A02),
102 borderRadius: BorderRadius.circular(4.0)
103 ),
104 child: Center(
105 child: Text(
106 '$conta',
107 style: TextStyle(fontSize: 20.0)
108 ),
109 ),
110 ),
111 );
112 }
Open in app Get started

Portanto, utilizamos dois novos widgets: Column (Coluna) e Row (Linha). Acredito que
não é difícil adivinhar qual é o seu propósito.

No próximo artigo, vamos analisá-los com mais precisão. Também aprenderemos como
montar diversos widgets e criar um aplicativo sensacional utilizando a biblioteca
Material do Flutter.

Recursos Adicionais
Se você deseja aprender mais sobre os tópicos mencionados, aqui está a lista de links
interessantes:

https://flutter.io/docs/get-started/flutter-for/web-devs

Escrevendo código utilizando VS Code e IntelliJ

Mais detalhes em widgets

Também é importante ler sobre Hot reload para entender quando e porquê a sua
aplicação pode não atualizar automaticamente.
Open in app Get started

About Help Terms Privacy

Get the Medium app

Você também pode gostar