Escolar Documentos
Profissional Documentos
Cultura Documentos
MOBILE COM
FLUTTER BÁSICO
Apostila do aluno
1
FIT-F.24.01-02 Rev.C
2
Autores e Instrutores
FIT-F.24.01-02 Rev.C
3
APRESENTAÇÃO
Boa Leitura!!
FIT-F.24.01-02 Rev.C
4
Indicação de ícones
FIT-F.24.01-02 Rev.C
5
Sumário
1. Android e IoS .................................................................................. 6
2. História do iOS.............................................................................. 11
FIT-F.24.01-02 Rev.C
6
3.23 Condicionais........................................................................... 61
5 Publicação de Aplicativo nas Lojas: Google Play e Apple Store .... 102
Referências.......................................................................................... 108
FIT-F.24.01-02 Rev.C
6
1. Android e IoS
FIT-F.24.01-02 Rev.C
7
FIT-F.24.01-02 Rev.C
8
FIT-F.24.01-02 Rev.C
9
FIT-F.24.01-02 Rev.C
11
2. História do iOS
FIT-F.24.01-02 Rev.C
12
FIT-F.24.01-02 Rev.C
13
FIT-F.24.01-02 Rev.C
14
Figura 5 - Ilustração do acesso direto aos recursos nativos no Flutter. Fonte: treinaweb.’
FIT-F.24.01-02 Rev.C
15
FIT-F.24.01-02 Rev.C
16
III. Verifique na sua pasta de Download se o arquivo foi salvo no formato Zip,
transfira- o para outro pasta, recomendamos criar uma pasta na raiz com
o nome src e inicie a instalação do Flutter neste diretório. O caminho final
da instalação deverá ser c:\src\flutter.
FIT-F.24.01-02 Rev.C
17
FIT-F.24.01-02 Rev.C
18
FIT-F.24.01-02 Rev.C
19
FIT-F.24.01-02 Rev.C
20
FIT-F.24.01-02 Rev.C
21
FIT-F.24.01-02 Rev.C
22
FIT-F.24.01-02 Rev.C
23
FIT-F.24.01-02 Rev.C
24
FIT-F.24.01-02 Rev.C
25
FIT-F.24.01-02 Rev.C
26
3.6 Emulador
FIT-F.24.01-02 Rev.C
27
FIT-F.24.01-02 Rev.C
28
FIT-F.24.01-02 Rev.C
29
FIT-F.24.01-02 Rev.C
30
FIT-F.24.01-02 Rev.C
31
FIT-F.24.01-02 Rev.C
32
FIT-F.24.01-02 Rev.C
33
II. Em SDK Manager, acesse a guia SDK tools e desmarque a opção hide
obsolete package:
FIT-F.24.01-02 Rev.C
34
FIT-F.24.01-02 Rev.C
35
FIT-F.24.01-02 Rev.C
36
FIT-F.24.01-02 Rev.C
37
Esse passo é Opcional, visto que se você quiser utilizar o Android Studio
sem problemas. Porém, o Android Studio exige mais recursos de hardware do
computador e se você possui um computador com pouca capacidade de
processamento e memória, o uso do VS Code é uma alternativa interessante.
Os passos a seguir valem também para as plataformas Linux e Mac.
FIT-F.24.01-02 Rev.C
38
FIT-F.24.01-02 Rev.C
39
FIT-F.24.01-02 Rev.C
40
FIT-F.24.01-02 Rev.C
41
FIT-F.24.01-02 Rev.C
42
III. Emulador configurado, vamos agora criar no 1º. Projeto Hello World.
Ainda na console do Flutter, digite flutter create hello_world, e veja
a criação do projeto, conforme abaixo:
FIT-F.24.01-02 Rev.C
43
FIT-F.24.01-02 Rev.C
44
FIT-F.24.01-02 Rev.C
45
Figura 54 - Android Studio, abrindo projeto Hello World. Fonte: autoria própria.
VI. Para abrir o projeto criado, no menu principal, click em File, Open
Project e localizem o arquivo hello_world e click em ok. O Android
Studio abrirá o arquivo main,dart onde iremos escrever nosso código.
VII. Nosso próximo passo será ativar o emulador dentro do Android Studio
da seguinte maneira: no canto direito da janela principal, clique no
ícone no formato de um celular, conforme abaixo:
FIT-F.24.01-02 Rev.C
46
VIII. Agora iremos voltar para a tela do nosso main.dart para finalmente
executarmos nosso programa Hello World, apague todo o código
existente e digite o seguinte código no Android Studio:
import 'package:flutter/widgets.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
FIT-F.24.01-02 Rev.C
47
FIT-F.24.01-02 Rev.C
48
XII. Para iniciar o código, aperte as teclas CRTL + F5. No topo superior do
Visual Studio Code abrirá uma pequena aba. Se você já possui
emuladores configurados, eles devem aparecer nessa aba. Se não,
basta selecionar a opção “Create New”:
FIT-F.24.01-02 Rev.C
49
FIT-F.24.01-02 Rev.C
50
FIT-F.24.01-02 Rev.C
51
FIT-F.24.01-02 Rev.C
52
FIT-F.24.01-02 Rev.C
53
3.13 Layout
FIT-F.24.01-02 Rev.C
54
FIT-F.24.01-02 Rev.C
55
FIT-F.24.01-02 Rev.C
56
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
splashColor: Colors.blueAccent,
onPressed: () {
/*...*/
},
child: Text(
"FlatButton",
style: TextStyle(fontSize: 20.0),
),
)
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('Exibindo imagem local')),
body: Column(
children: <Widget>[
Image.asset(
'imagens/logomac.png',
),
Text('Macoratti.net')
],
),
),
);
}
}
Figura 70 - Widget Botão (Button). Fonte: autoria própria.
FIT-F.24.01-02 Rev.C
57
Fortemente tipada, significa que uma vez que a variável foi declarada com
um tipo ela será até o seu fim do mesmo tipo e também normalmente
possuem declaração explicita de tipo onde o tipo da variável deve ser
especificado logo na sua declaração;
FIT-F.24.01-02 Rev.C
58
3.20 Variáveis
void main() {
// Variável que armazena números inteiros
int idade = 33;
print("Idade: $idade");
FIT-F.24.01-02 Rev.C
59
dynamic x = 10;
print(x);
O resultado será:
FIT-F.24.01-02 Rev.C
60
3.21 Operadores
Os tipos int, double e num (pode ser inteiro ou ponto flutuante)
fornecem diversos métodos e propriedades que podem ser utilizados para
a transformação e checagem de dados.
Abaixo apresentamos os operadores de comparação e simples,
utilizados no Dart:
Operador Descrição
>= Maior ou igual
> Maior
<= Menor ou igual
< Menor
|s Mesmo tipo
|s! Não é mesmo tipo
== Igual
!= Diferente
&& E” lógico (AND)
|| E” lógico (AND)
+ Adição
- Subtração
* Multiplicação
/ Divisão
% Percentual (resto da divisão)
Tabela 1 - Tipos de operadores de comparação. Fonte: autoria própria.
FIT-F.24.01-02 Rev.C
61
3.23 Condicionais
As Condicionais são utilizadas para tomada de decisão no código, sendo:
void main(){
double media = 4.9;
linguagem = "Dart";
print(linguagem ?? "Não Informado");
FIT-F.24.01-02 Rev.C
62
3.24 Repetições
void main(){
// Repetição de 0 a 5 (conhecemos o número inicial e final)
// FOR (INICIO; CONDIÇÃO; INCREMENTO)
for(int i = 0; i < 5; i++){
print(i);
}
// Repetição de 0 a 5
// INICIO; WHILE (CONDICAO){ INCREMENTO; }
// Teste condicional no início
int j = 0; // Início
while(j < 5){ // Condição
print(j);
j++; // Incremento
}
// Repetição de 0 a 5
// INICIO; DO { INCREMENTO; } WHILE(CONDICAO);
// Teste condicional no final
int k = 0; // Início
do {
print(k);
k++; // Incremento
} while(k < 5); // Condição
// FOREACH
// FOR (VARIAVEL DENTRO DO CONJUNTO)
for (int numero in numeros){
print(numero);
}
}
Figura 75 - Repetições DART. Fonte: autoria própria.
3.25 Funções
FIT-F.24.01-02 Rev.C
64
// Função principal
void main() {
// Executando a função escreverBemVindo()
escreverBemVindo();
FIT-F.24.01-02 Rev.C
65
FIT-F.24.01-02 Rev.C
66
4 Exercícios Práticos
FIT-F.24.01-02 Rev.C
67
void main() {
runApp(
MaterialApp(
home: Center(
child: Container(
),
),
),
);
}
Figura 79 – Código Widget Tree. Fonte: autoria própria.
FIT-F.24.01-02 Rev.C
68
FIT-F.24.01-02 Rev.C
69
FIT-F.24.01-02 Rev.C
70
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: "Layout",
home: Scaffold(
appBar: AppBar(
),
body: Center(
child: Container(
child: Column(
children: [
Container(
height: 50,
width: 50,
color: Colors.orange,
child: Center(
child: Text("orange"),
FIT-F.24.01-02 Rev.C
71
),
),
Padding(
padding: EdgeInsets.all(5),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 50,
width: 50,
color: Colors.amber,
child: Center(
child: Text("Amber"),
),
),
Padding(padding: EdgeInsets.all(5)),
Container(
height: 50,
FIT-F.24.01-02 Rev.C
72
width: 50,
color: Colors.green,
),
],
),
Padding(padding: EdgeInsets.all(5)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 50,
width: 50,
color: Colors.grey,
),
Padding(padding: EdgeInsets.all(5)),
Container(
height: 50,
width: 50,
color: Colors.deepOrange,
),
Padding(padding: EdgeInsets.all(5)),
Container(
FIT-F.24.01-02 Rev.C
73
height: 50,
width: 50,
color: Colors.indigo,
],
),
],
),
),
),
),
),
);
FIT-F.24.01-02 Rev.C
74
FIT-F.24.01-02 Rev.C
75
FIT-F.24.01-02 Rev.C
76
import 'package:flutter/material.dart';
void main() {
runApp(
home(),
);
FIT-F.24.01-02 Rev.C
77
@override
return MaterialApp(
home: Scaffold(
//backgroundColor: Colors.grey,
appBar: AppBar(
backgroundColor: Colors.indigo,
),
drawer: Drawer(
child: menu(),
),
//plano de fundo
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("asset/imagem/fundo.webp"),
fit: BoxFit.cover,
),
FIT-F.24.01-02 Rev.C
78
),
child: conteudo(),
),
),
);
@override
return Column(
children: [
FlutterLogo(),
Text("Desenvolvido por:"),
Text("Bruno Rodrigues"),
Icon(
Icons.copyright,
),
],
);
FIT-F.24.01-02 Rev.C
79
@override
return Center(
child: Column(
children: [
Text("Minhas viagens"),
Padding(padding: EdgeInsets.all(20)),
Container(
height: 200,
width: 200,
child: Image.asset("asset/imagem/barco.jpg"),
),
Padding(padding: EdgeInsets.all(15)),
Container(
height: 200,
width: 200,
child: Image.network(
FIT-F.24.01-02 Rev.C
80
"https://www.showmetech.com.br/wp-
content/uploads//2019/12/painel-sublimado-3d-tecido-fundo-do-
mar-0002-3x2m-D_NQ_NP_920421-MLB28584404262_112018-F.jpg"),
),
Padding(padding: EdgeInsets.all(10)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Curta e compartilhe"),
Icon(
Icons.thumb_up,
),
],
),
],
),
);
FIT-F.24.01-02 Rev.C
81
FIT-F.24.01-02 Rev.C
82
FIT-F.24.01-02 Rev.C
83
import 'package:flutter/material.dart';
void main() {
runApp(
home(),
);
FIT-F.24.01-02 Rev.C
84
@override
return MaterialApp(
//home: pagina1(),
//home: pagina2(),
//home: login(),
routes: {
},
);
@override
return Scaffold(
appBar: AppBar(
FIT-F.24.01-02 Rev.C
85
),
drawer: Drawer(
child: menu(),
),
body: Container(
child: conteudoPagina1(),
),
);
@override
return Column(
children: [
FlutterLogo(),
Text("Desenvolvido por:"),
Text("Bruno Rodrigues"),
TextButton(
onPressed: () {
FIT-F.24.01-02 Rev.C
86
Navigator.popAndPushNamed(context, "pagina1");
},
),
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "pagina2");
},
),
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "/");
},
child: Text("Logoff"),
),
Icon(
Icons.copyright,
),
],
);
FIT-F.24.01-02 Rev.C
87
@override
_conteudoPagina1State();
@override
return Center(
child: Column(
children: [
Container(
height: 200,
width: 200,
color: cor1,
),
FIT-F.24.01-02 Rev.C
88
Padding(padding: EdgeInsets.all(5)),
Container(
height: 200,
width: 200,
color: cor2,
),
Padding(padding: EdgeInsets.all(20)),
Switch(
value: status,
onChanged: (value) {
status = value;
print("$status");
setState(() {});
if (status) {
cor1 = Colors.purple;
cor2 = Colors.brown;
} else {
cor1 = Colors.green;
cor2 = Colors.yellow;
},
),
FIT-F.24.01-02 Rev.C
89
Padding(padding: EdgeInsets.all(20)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "pagina2");
},
style: TextButton.styleFrom(
primary: Colors.white,
fundo
onSurface: Colors.grey,
botão ou
fixo da margem
shape: RoundedRectangleBorder(
FIT-F.24.01-02 Rev.C
90
borderRadius: BorderRadius.circular(24),
),
),
),
Padding(padding: EdgeInsets.all(5)),
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "/");
},
child: Text("Logoff"),
style: TextButton.styleFrom(
primary: Colors.white,
fundo
onSurface: Colors.grey,
botão ou
fixo da margem
shape: RoundedRectangleBorder(
FIT-F.24.01-02 Rev.C
91
borderRadius: BorderRadius.circular(24),
),
),
),
],
),
],
),
);
@override
return Scaffold(
appBar: AppBar(
FIT-F.24.01-02 Rev.C
92
backgroundColor: Colors.brown,
),
drawer: Drawer(
child: menu(),
),
body: Container(
child: conteudoPagina2(),
),
);
@override
_conteudoPagina2State();
double tamanho = 0;
int num = 0;
@override
FIT-F.24.01-02 Rev.C
93
return Center(
child: Column(
children: [
Slider(
value: tamanho,
onChanged: (value) {
tamanho = value;
num = tamanho.toInt();
print("$tamanho");
setState(() {});
},
min: 0,
max: 100,
),
Text(
"$num",
style: TextStyle(
fontSize: tamanho,
),
),
Padding(padding: EdgeInsets.all(20)),
FIT-F.24.01-02 Rev.C
94
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "pagina1");
},
style: TextButton.styleFrom(
primary: Colors.white,
fundo
onSurface: Colors.grey,
botão ou
fixo da margem
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
FIT-F.24.01-02 Rev.C
95
),
),
),
Padding(padding: EdgeInsets.all(5)),
TextButton(
onPressed: () {
Navigator.popAndPushNamed(context, "/");
},
child: Text("Logoff"),
style: TextButton.styleFrom(
primary: Colors.white,
fundo
onSurface: Colors.grey,
botão ou
fixo da margem
shape: RoundedRectangleBorder(
FIT-F.24.01-02 Rev.C
96
borderRadius: BorderRadius.circular(24),
),
),
),
],
),
],
),
);
@override
return Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
FIT-F.24.01-02 Rev.C
97
image: DecorationImage(
image: NetworkImage(
"http://caminhandoembeleza.com/wp-
content/uploads/2020/12/03191435682598.gif"),
fit: BoxFit.cover,
),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
onChanged: (value) {
email = value;
print("$email");
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'email',
border: OutlineInputBorder(),
FIT-F.24.01-02 Rev.C
98
),
),
Padding(padding: EdgeInsets.all(5)),
TextField(
onChanged: (value) {
senha = value;
},
obscureText: true,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'senha',
border: OutlineInputBorder(),
),
),
Padding(padding: EdgeInsets.all(10)),
TextButton(
onPressed: () {
print("Entrada autorizada");
FIT-F.24.01-02 Rev.C
99
Navigator.popAndPushNamed(context,
"pagina1");
} else {
showDialog(
context: context,
return AlertDialog(
incorreto"),
actions: [
TextButton(
onPressed: () {},
child: Text("Sim"),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("Não"),
),
FIT-F.24.01-02 Rev.C
100
],
);
});
},
child: Text("Login"),
style: TextButton.styleFrom(
primary: Colors.white,
fundo
onSurface: Colors.grey,
botão ou
fixo da margem
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
),
FIT-F.24.01-02 Rev.C
101
),
],
),
),
),
);
}
Figura 94 – Código Aplicativo com várias páginas. Fonte: autoria própria.
FIT-F.24.01-02 Rev.C
102
FIT-F.24.01-02 Rev.C
103
FIT-F.24.01-02 Rev.C
104
FIT-F.24.01-02 Rev.C
105
6 Desafio
Código-fonte;
Imagens da execução do aplicativo com todas as etapas e telas, até o
resultado final do programa.
FIT-F.24.01-02 Rev.C
106
FIT-F.24.01-02 Rev.C
107
Conclusão
FIT-F.24.01-02 Rev.C
108
Referências
Apps nativos para Android e IOS com Flutter, crie Apps como: Youtube,
WhatsApp, Uber, OLX e muito mais! em: https://fit-
tecnologia.udemy.com/course/desenvolvimento-android-e-ios-com-
flutter/learn/lecture/13537448#overview – acessado em outubro/2021
FIT-F.24.01-02 Rev.C
109
FIT-F.24.01-02 Rev.C
110
FIT-F.24.01-02 Rev.C
111
FIT-F.24.01-02 Rev.C