Mudanças entre as edições de "Flutter - Introdução"

De Aulas
 
(23 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
 +
 +
 +
 +
 +
 
Afluentes: [[Dispositivos Móveis]]; [[Usabilidade, desenvolvimento web, mobile e jogos]]
 
Afluentes: [[Dispositivos Móveis]]; [[Usabilidade, desenvolvimento web, mobile e jogos]]
  
Linha 8: Linha 13:
  
 
Antes de instalar o Flutter, é necessário instalarmos o SDK da plataforma para qual vamos desenvolver. Se for para Android, então é necessário instalar o SDK do Android. Ele já é instalado quando instalamos o Android Studio.
 
Antes de instalar o Flutter, é necessário instalarmos o SDK da plataforma para qual vamos desenvolver. Se for para Android, então é necessário instalar o SDK do Android. Ele já é instalado quando instalamos o Android Studio.
 +
 +
Veja que você pode usar algum ambiente de desenvolvimento web, tal como o [https://flutlab.io/ FlutLab] para criar APP em Flutter. Contudo, você pode encontrar diversas limitações, então o ideal é instalar no seu PC.
  
 
Para instalar o Flutter, propriamente dito, você precisa instalar o Flutter SDK. Nele já vem a ferramenta de linha de comando do flutter (CLI), o compilador da linguagem de programação Dart, o ''framework'' e outras ferramentas.
 
Para instalar o Flutter, propriamente dito, você precisa instalar o Flutter SDK. Nele já vem a ferramenta de linha de comando do flutter (CLI), o compilador da linguagem de programação Dart, o ''framework'' e outras ferramentas.
Linha 32: Linha 39:
 
  flutter --version
 
  flutter --version
  
E vai aparecer algo como:
+
E vai aparecer algo como:<syntaxhighlight lang="text">
 
+
Flutter 3.29.3 • channel stable • https://github.com/flutter/flutter.git
Flutter 3.3.2 • channel stable • https://github.com/flutter/flutter.git
+
Framework • revision ea121f8859 (5 weeks ago) • 2025-04-11 19:10:07 +0000
Framework • revision e3c29ec00c (9 days ago) • 2022-09-14 08:46:55 -0500
+
Engine • revision cf56914b32
Engine • revision a4ff2c53d8
+
Tools • Dart 3.7.2 • DevTools 2.42.3
Tools • Dart 2.18.1 • DevTools 2.15.0
+
</syntaxhighlight>Outro comando importante pra ver se está tudo certo para começarmos a trabalhar com o flutter é o
 
 
Outro comando importante pra ver se está tudo certo para começarmos a trabalhar com o flutter é o
 
  
 
  flutter doctor
 
  flutter doctor
  
Esse comando vai verificar se todas as dependências são satisfeitas. Se estiver tudo certo, você vai ver algo como:
+
Esse comando vai verificar se todas as dependências são satisfeitas. Se estiver tudo certo, você vai ver algo como:<syntaxhighlight lang="text">
 +
Doctor summary (to see all details, run flutter doctor -v):
 +
[✓] Flutter (Channel stable, 3.29.3, on Ubuntu 25.04 6.14.0-15-generic, locale pt_BR.UTF-8)
 +
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
 +
[✓] Chrome - develop for the web
 +
[✓] Linux toolchain - develop for Linux desktop
 +
[✓] Android Studio (version 2024.3)
 +
[✓] VS Code (version 1.100.2)
 +
[✓] Connected device (2 available)
 +
[✓] Network resources
  
Doctor summary (to see all details, run flutter doctor -v):
+
• No issues found!
[✓] Flutter (Channel stable, 3.3.2, on Ubuntu 22.04.1 LTS 5.15.0-48-generic,
+
</syntaxhighlight>Caso contrário, você terá que instalar e resolver as dependências antes de continuar.
    locale pt_BR.UTF-8)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
 
[✓] Chrome - develop for the web
 
[✓] Linux toolchain - develop for Linux desktop
 
[✓] Android Studio (version 4.1)
 
[✓] Android Studio (version 2021.2)
 
[✓] VS Code (version 1.71.2)
 
[✓] Connected device (2 available)
 
[✓] HTTP Host Availability
 
 
• No issues found!
 
 
 
Caso contrário, você terá que instalar e resolver as dependências antes de continuar.
 
  
 
Veja que no meu caso está instalado o Flutter, o Android Studio, o Android toolchain, o Chrome com seu ambiente para desenvolvedores, o VS Code e já tenho um dispositivo (ou máquina virtual) que já criei com o AVD.
 
Veja que no meu caso está instalado o Flutter, o Android Studio, o Android toolchain, o Chrome com seu ambiente para desenvolvedores, o VS Code e já tenho um dispositivo (ou máquina virtual) que já criei com o AVD.
Linha 67: Linha 68:
 
  flutter emulators
 
  flutter emulators
  
podemos ver os meus emuladores criados:
+
podemos ver os meus emuladores criados:<syntaxhighlight lang="text">
 +
1 available emulator:
  
1 available emulator:
+
Id                  • Name                • Manufacturer • Platform
  
Nexus_5X_API_28 Nexus 5X API 28 Google • android
+
Medium_Phone_API_36 Medium Phone API 36 Generic      • android
  
To run an emulator, run 'flutter emulators --launch <emulator id>'.
+
To run an emulator, run 'flutter emulators --launch <emulator id>'.
To create a new emulator, run 'flutter emulators --create [--name xyz]'.
+
To create a new emulator, run 'flutter emulators --create [--name xyz]'.
 
You can find more information on managing emulators at the links below:
 
  https://developer.android.com/studio/run/managing-avds
 
  https://developer.android.com/studio/command-line/avdmanager
 
  
No caso eu só criei um, o <code>Nexus_5X_API_28</code>.
+
You can find more information on managing emulators at the links below:
 +
  https://developer.android.com/studio/run/managing-avds
 +
  https://developer.android.com/studio/command-line/avdmanager
 +
</syntaxhighlight>No caso eu só tenho um, o <code>Medium_Phone_API_36</code>.
  
 
Agora, se você conectou um smartphone ou tablet e quer ver os dispositivos conectados, use o comand
 
Agora, se você conectou um smartphone ou tablet e quer ver os dispositivos conectados, use o comand
Linha 86: Linha 87:
 
  flutter devices
 
  flutter devices
  
que vai mostrar, por exemplo:
+
que vai mostrar, por exemplo:<syntaxhighlight lang="text">
 +
Found 3 connected devices:
 +
  sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64    • Android 16 (API 36) (emulator)
 +
  Linux (desktop)              • linux        • linux-x64      • Ubuntu 25.04 6.14.0-15-generic
 +
  Chrome (web)                • chrome        • web-javascript • Google Chrome 135.0.7049.84
  
3 connected devices:
+
Run "flutter emulators" to list and start any available device emulators.
 
AOSP on IA Emulator (mobile) • emulator-5554 • android-x86    • Android 9 (API 28) (emulator)
 
Linux (desktop)              • linux        • linux-x64      • Ubuntu 22.04.1 LTS 5.15.0-48-generic
 
Chrome (web)                • chrome        • web-javascript • Google Chrome 105.0.5195.125
 
  
Veja que o primeiro que mostra pra mim é o meu emulador, que está aberto, o segundo é o desktop e o terceiro é o Chrome. Se o meu smartphone estiver conectado, ele aparece também e ao executar a aplicação, vai rodar nele, se ele não estiver conectado, não vai aparecer meu smartphone e a aplicação vai abrir no emulador. Se o emulador não estiver aberto, abre no Desktop, e assim por diante.
+
If you expected another device to be detected, please run "flutter doctor" to diagnose potential issues. You
 +
may also try increasing the time to wait for connected devices with the "--device-timeout" flag. Visit
 +
https://flutter.dev/setup/ for troubleshooting tips.
 +
</syntaxhighlight>Veja que o primeiro que mostra pra mim é o meu emulador, que está aberto, o segundo é o desktop Linux (eu uso Linux) e o terceiro é o navegador web Google Chrome. Se o meu smartfone estiver conectado, ele aparece também nessa lista e ao executar a aplicação, vai rodar nele, se ele não estiver conectado, não vai aparecer meu smartfone e a aplicação vai abrir no segundo da lista, o emulador. Se o emulador não estiver aberto, abre no Desktop, e assim por diante.
  
 
= Hello World =
 
= Hello World =
  
Com tudo instalado e verificado, agora vamos criar nosso primeiro ''Hello World'' no Flutter. Para o exemplo rodar, vamos iniciar nossa máquina virtual. No meu caso, já descrito acima, é a <code>Nexus_5X_API_28</code>, então executo comando:
+
Com tudo instalado e verificado, agora vamos criar nosso primeiro ''Hello World'' no Flutter. Para o exemplo rodar, vamos iniciar nossa máquina virtual. No meu caso, já descrito acima, é a <code>Medium_Phone_API_36</code>, então executo comando:
  
  flutter emulators --launch Nexus_5X_API_28
+
  flutter emulators --launch Medium_Phone_API_36
  
 
E aguardamos a máquina virtual abrir. É meio demoradinho sim, então paciência.
 
E aguardamos a máquina virtual abrir. É meio demoradinho sim, então paciência.
Linha 122: Linha 126:
 
Então vamos direto para o arquivo principal do programa que é o <code>lib/main.dart</code>. Apagamos todo o conteúdo e vamos reescrevê-lo da seguinte forma:
 
Então vamos direto para o arquivo principal do programa que é o <code>lib/main.dart</code>. Apagamos todo o conteúdo e vamos reescrevê-lo da seguinte forma:
  
<syntaxhighlight lang=dart line>
+
<syntaxhighlight lang=dart>
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
  
Linha 129: Linha 133:
 
     home: Scaffold(
 
     home: Scaffold(
 
       appBar: AppBar(
 
       appBar: AppBar(
         title: Text('Hello!'),
+
         title: const Text('Hello!'),
 
       ),
 
       ),
       body: Text('Hello World'),
+
       body: const Text('Hello World'),
 
     ),
 
     ),
 
   ));
 
   ));
Linha 151: Linha 155:
 
Vamos criar um arquivo <code>app.dart</code> dentro da pasta <code>lib</code> e colocar o seguinte código:
 
Vamos criar um arquivo <code>app.dart</code> dentro da pasta <code>lib</code> e colocar o seguinte código:
  
<syntaxhighlight lang=dart line>
+
<syntaxhighlight lang=dart>
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
  
 
class App extends StatelessWidget {
 
class App extends StatelessWidget {
 +
  const App({super.key});
 +
 
   @override
 
   @override
 
   Widget build(BuildContext context) {
 
   Widget build(BuildContext context) {
 
     return Scaffold(
 
     return Scaffold(
 
       appBar: AppBar(
 
       appBar: AppBar(
         title: Text('Hello!'),
+
         title: const Text('Hello!'),
 
       ),
 
       ),
       body: Text('Hello World'),
+
       body: const Text('Hello World'),
 
     );
 
     );
 
   }
 
   }
Linha 171: Linha 177:
 
Já o <code>main.dart</code> vai ficar mais simples:
 
Já o <code>main.dart</code> vai ficar mais simples:
  
<syntaxhighlight lang=dart line>
+
<syntaxhighlight lang="dart">
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
 
import 'app.dart';
 
import 'app.dart';
  
void main() {
+
void main() => runApp(const MaterialApp(home: App()));
  runApp(
 
    MaterialApp(home: App()),
 
  );
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Linha 191: Linha 193:
  
 
* '''.idea/:''' criada para configurações das ferramentas do Android Studio, caso você o use como IDE.
 
* '''.idea/:''' criada para configurações das ferramentas do Android Studio, caso você o use como IDE.
* '''android/ e ios/:''' possui arquivos para gerar o pacote do aplicativo dessas plataformas.
+
* '''android/, ios/, linux/, macos/, web/ e windows/:''' possui arquivos para gerar o pacote do aplicativo dessas plataformas.
 
* '''build/:''' build do projeto em Dart gerado quando rodarmos o comando <code>flutter run</code>.
 
* '''build/:''' build do projeto em Dart gerado quando rodarmos o comando <code>flutter run</code>.
 
* '''test/:''' pasta para os testes da aplicação,
 
* '''test/:''' pasta para os testes da aplicação,
Linha 208: Linha 210:
  
 
<center>[[Image:Flutter_anatomy_scheme.png]]</center>
 
<center>[[Image:Flutter_anatomy_scheme.png]]</center>
 +
 +
{{tip|Antes precisava do Container, conforme imagem acima. Agora não precisa mais e usamos direto Column.}}
  
 
Primeiro vamos colocar uma imagem no projeto para usarmos. Escolham uma imagem quadrada que quiserem e colocem em uma nova pasta criada na raíz do projeto chamada <code>images</code>. Eu peguei uma imagem da Arisa chamada <code>arisa.png</code>
 
Primeiro vamos colocar uma imagem no projeto para usarmos. Escolham uma imagem quadrada que quiserem e colocem em uma nova pasta criada na raíz do projeto chamada <code>images</code>. Eu peguei uma imagem da Arisa chamada <code>arisa.png</code>
Linha 219: Linha 223:
 
Descomente e coloque o link da imagem. Algo como:
 
Descomente e coloque o link da imagem. Algo como:
  
  # assets:
+
  assets:
    - images/arisa.png
+
  - images/arisa.png
  
 
Salve o arquivo e feche.
 
Salve o arquivo e feche.
  
Agora podemos criar nosso programa:
+
Depois de editar o arquivo <code>pubspec.yaml</code> utilize o comando abaixo para atualizar o projeto:<syntaxhighlight lang="text">
 +
flutter pub get
 +
</syntaxhighlight>Agora podemos criar nosso programa:
  
 
Com base no esquema acima, vemos um <code>Scanffold</code>, um widget que nos dá uma tela em branco.
 
Com base no esquema acima, vemos um <code>Scanffold</code>, um widget que nos dá uma tela em branco.
Linha 232: Linha 238:
 
Dentro do Container colocamos um <code>Column</code>. Os elementos dentro do Column ficão ali organizados em pilha verticalmente. O primeiro elemento dentro do Column é uma imagem e depoi suma <code>Row</code>. Na Row, podemos organizar os elementos horizontalmente. Alí colocamos dois elementos tipo <code>Text</code> e abaixo da Row colocamos um <code>TextField</code>
 
Dentro do Container colocamos um <code>Column</code>. Os elementos dentro do Column ficão ali organizados em pilha verticalmente. O primeiro elemento dentro do Column é uma imagem e depoi suma <code>Row</code>. Na Row, podemos organizar os elementos horizontalmente. Alí colocamos dois elementos tipo <code>Text</code> e abaixo da Row colocamos um <code>TextField</code>
  
; main.dart
+
== main.dart ==
<syntaxhighlight lang=dart line>
+
<syntaxhighlight lang=dart>
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
 
import 'app.dart';
 
import 'app.dart';
  
 
void main() {
 
void main() {
   runApp(MaterialApp(
+
   runApp(const MaterialApp(
 
     home: App(),
 
     home: App(),
 
   ));
 
   ));
Linha 244: Linha 250:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
; app.dart
+
== app.dart ==
<syntaxhighlight lang=dart line>
+
<syntaxhighlight lang="dart">
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
  
 
class App extends StatelessWidget {
 
class App extends StatelessWidget {
 +
  const App({super.key});
 +
 
   @override
 
   @override
 
   Widget build(BuildContext context) {
 
   Widget build(BuildContext context) {
 
     return Scaffold(
 
     return Scaffold(
       appBar: AppBar(
+
       appBar: AppBar(title: const Text('Hello!')),
        title: Text('Hello!'),
+
       body: const Column(
      ),
+
         children: [
       body: Container(
+
          Center(
         child: Column(
+
            child: Image(image: AssetImage('images/arisa.png'), width: 300),
          children: [
+
          ),
            Center(
+
          Row(children: [Text('Name: '), Text('Arisa')]),
              child: Image(
+
          TextField(),
                image: AssetImage('images/arisa.png'),
+
        ],
              ),
 
            ),
 
            Row(
 
              children: [
 
                Text('Name: '),
 
                Text('Arisa'),
 
              ],
 
            ),
 
            TextField(),
 
          ],
 
        ),
 
 
       ),
 
       ),
 
     );
 
     );
Linha 284: Linha 281:
 
Vamos fazer um exemplo básico em que temos dois campos texto onde digitamos o nome, no primeiro, o sobrenome no segundo e um botão para concatenar os dois campos e colocar o conteúdo em um terceiro, não editável. Segue o código:
 
Vamos fazer um exemplo básico em que temos dois campos texto onde digitamos o nome, no primeiro, o sobrenome no segundo e um botão para concatenar os dois campos e colocar o conteúdo em um terceiro, não editável. Segue o código:
  
<syntaxhighlight lang=Dart line>
+
<syntaxhighlight lang="dart">
 
import 'package:flutter/material.dart';
 
import 'package:flutter/material.dart';
  
 
class App extends StatefulWidget {
 
class App extends StatefulWidget {
 +
  const App({super.key});
 +
 
   @override
 
   @override
   _AppState createState() => _AppState();
+
   State<App> createState() => _AppState();
 
}
 
}
  
 
class _AppState extends State<App> {
 
class _AppState extends State<App> {
   TextEditingController _name = TextEditingController();
+
   final TextEditingController _name = TextEditingController();
   TextEditingController _surname = TextEditingController();
+
   final TextEditingController _surname = TextEditingController();
   TextEditingController _fullname = TextEditingController();
+
   final TextEditingController _fullname = TextEditingController();
 +
 
 
   @override
 
   @override
 
   Widget build(BuildContext context) {
 
   Widget build(BuildContext context) {
 
     return Scaffold(
 
     return Scaffold(
       appBar: AppBar(
+
       appBar: AppBar(title: const Text('Concatenação!')),
        title: Text('Concatenação!'),
+
       body: Column(
      ),
+
         children: [
       body: Container(
+
          TextField(
         child: Column(
+
            style: const TextStyle(fontSize: 25, color: Colors.green),
          children: [
+
            decoration: const InputDecoration(labelText: 'Digite o seu nome'),
            TextField(
+
            // Para campos tipo senha usar
              style: TextStyle(
+
            // obscureText: true,
                fontSize: 25,
 
                color: Colors.green,
 
              ),
 
              decoration: InputDecoration(
 
                labelText: 'Digite o seu nome',
 
              ),
 
              // Para campos tipo senha
 
              // obscureText: true,
 
  
              // onChange e chamado a cada interacao
+
            // onChange - chamado a cada interacao
              // onSubmitted so quando termina de digitar
+
            // onSubmitted so quando termina de digitar
              onSubmitted: (String texto) {
+
            onChanged: (String texto) {
                print('valor digitado ' + texto);
+
              print('valor digitado $texto');
              },
+
            },
              controller: _name,
+
            controller: _name,
 +
          ),
 +
          TextField(
 +
            style: const TextStyle(fontSize: 25, color: Colors.green),
 +
            decoration: const InputDecoration(
 +
              labelText: 'Digite o seu sobrenome',
 
             ),
 
             ),
             TextField(
+
             controller: _surname,
              style: TextStyle(
+
          ),
                fontSize: 25,
+
          ElevatedButton(
                color: Colors.green,
+
            child: const Text('Concatenar'),
              ),
+
            onPressed: () {
              decoration: InputDecoration(
+
              _fullname.text = '${_name.text} ${_surname.text}';
                labelText: 'Digite o seu sobrenome',
+
            },
              ),
+
          ),
              controller: _surname,
+
          TextField(
            ),
+
            style: const TextStyle(fontSize: 25, color: Colors.green),
            ElevatedButton(
+
            enabled: false,
              child: Text('Concatenar'),
+
            controller: _fullname,
              onPressed: () {
+
          ),
                _fullname.text = _name.text + ' ' + _surname.text;
+
        ],
              },
 
            ),
 
            TextField(
 
              style: TextStyle(
 
                fontSize: 25,
 
                color: Colors.green,
 
              ),
 
              enabled: false,
 
              controller: _fullname,
 
            ),
 
          ],
 
        ),
 
 
       ),
 
       ),
 
     );
 
     );
 
   }
 
   }
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Edição atual tal como às 20h37min de 21 de maio de 2025



Afluentes: Dispositivos Móveis; Usabilidade, desenvolvimento web, mobile e jogos

Flutter

Flutter é o kit de ferramentas de Interface do Usuário (UI) do Google para a construção de aplicativos nativos para celular, web e desktop a partir de uma única base de código.

Instalação

Antes de instalar o Flutter, é necessário instalarmos o SDK da plataforma para qual vamos desenvolver. Se for para Android, então é necessário instalar o SDK do Android. Ele já é instalado quando instalamos o Android Studio.

Veja que você pode usar algum ambiente de desenvolvimento web, tal como o FlutLab para criar APP em Flutter. Contudo, você pode encontrar diversas limitações, então o ideal é instalar no seu PC.

Para instalar o Flutter, propriamente dito, você precisa instalar o Flutter SDK. Nele já vem a ferramenta de linha de comando do flutter (CLI), o compilador da linguagem de programação Dart, o framework e outras ferramentas.

Além disso é necessário um dispositivo mobile para executar o aplicativo ou o emulador do Android ou iOS.

Não vou entrar no mérito do passo a passo da instalação aqui, mas vou passar alguns links que podem ajudá-los no processo.

Também vou passar alguns links que podem ser de grande importância para o aprendizado de vocês.

Verificando a Instalação

Se você já instalou o Flutter, podemos verificar se está tudo ok com o comando

flutter --version

E vai aparecer algo como:

Flutter 3.29.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ea121f8859 (5 weeks ago) • 2025-04-11 19:10:07 +0000
Engine • revision cf56914b32
Tools • Dart 3.7.2 • DevTools 2.42.3

Outro comando importante pra ver se está tudo certo para começarmos a trabalhar com o flutter é o

flutter doctor

Esse comando vai verificar se todas as dependências são satisfeitas. Se estiver tudo certo, você vai ver algo como:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.29.3, on Ubuntu 25.04 6.14.0-15-generic, locale pt_BR.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2024.3)
[✓] VS Code (version 1.100.2)
[✓] Connected device (2 available)
[✓] Network resources

• No issues found!

Caso contrário, você terá que instalar e resolver as dependências antes de continuar.

Veja que no meu caso está instalado o Flutter, o Android Studio, o Android toolchain, o Chrome com seu ambiente para desenvolvedores, o VS Code e já tenho um dispositivo (ou máquina virtual) que já criei com o AVD.

Com o comando

flutter emulators

podemos ver os meus emuladores criados:

1 available emulator:

Id                  • Name                • Manufacturer • Platform

Medium_Phone_API_36 • Medium Phone API 36 • Generic      • android

To run an emulator, run 'flutter emulators --launch <emulator id>'.
To create a new emulator, run 'flutter emulators --create [--name xyz]'.

You can find more information on managing emulators at the links below:
  https://developer.android.com/studio/run/managing-avds
  https://developer.android.com/studio/command-line/avdmanager

No caso eu só tenho um, o Medium_Phone_API_36.

Agora, se você conectou um smartphone ou tablet e quer ver os dispositivos conectados, use o comand

flutter devices

que vai mostrar, por exemplo:

Found 3 connected devices:
  sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64    • Android 16 (API 36) (emulator)
  Linux (desktop)              • linux         • linux-x64      • Ubuntu 25.04 6.14.0-15-generic
  Chrome (web)                 • chrome        • web-javascript • Google Chrome 135.0.7049.84

Run "flutter emulators" to list and start any available device emulators.

If you expected another device to be detected, please run "flutter doctor" to diagnose potential issues. You
may also try increasing the time to wait for connected devices with the "--device-timeout" flag. Visit
https://flutter.dev/setup/ for troubleshooting tips.

Veja que o primeiro que mostra pra mim é o meu emulador, que está aberto, o segundo é o desktop Linux (eu uso Linux) e o terceiro é o navegador web Google Chrome. Se o meu smartfone estiver conectado, ele aparece também nessa lista e ao executar a aplicação, vai rodar nele, se ele não estiver conectado, não vai aparecer meu smartfone e a aplicação vai abrir no segundo da lista, o emulador. Se o emulador não estiver aberto, abre no Desktop, e assim por diante.

Hello World

Com tudo instalado e verificado, agora vamos criar nosso primeiro Hello World no Flutter. Para o exemplo rodar, vamos iniciar nossa máquina virtual. No meu caso, já descrito acima, é a Medium_Phone_API_36, então executo comando:

flutter emulators --launch Medium_Phone_API_36

E aguardamos a máquina virtual abrir. É meio demoradinho sim, então paciência.

Agora vamos a criar o nosso projeto. Então escolha uma pasta de sua preferência no seu computador para colocar os seus projetos de Flutter e digite o comando

flutter create helloworld

E a plasta helloworld com o nosso projeto será criada. Abra essa pasta no Visual Studio Code.

É possível que o Visual Studio Code pedirá para você instalar os plugins necessários para trabalhar com Flutter e Dart, caso seja a primeira vez que você está abrindo um projeto Flutter.

Antes de fazer qualquer coisa, vamos rodar esse projeto gerado. Pode ser por um terminal separado ou abrindo um terminal no VSCode mesmo, mas precisa estar na pasta raiz do projeto. Digite:

flutter run


Tplnote Bulbgraph.png

Pra mostrar o terminal no VSCode use CTRL+` ou CTRL+SHIFT+ACENTO_AGUDO

Esse projeto criado não tem nada de incrível, é apenas um exemplo com alguns recursos, mas que pra gente, começando com um Hello World, vale mais a pena fazer do zero pra entender cada um dos pontos.

Então vamos direto para o arquivo principal do programa que é o lib/main.dart. Apagamos todo o conteúdo e vamos reescrevê-lo da seguinte forma:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const Text('Hello!'),
      ),
      body: const Text('Hello World'),
    ),
  ));
}

No caso, eu tenho instalado os plugins no meu VSCode e só clico no run no próprio código.

Bem, o Hello World acima é composto de um MaterialApp, que é um widget bastante conveniente para criar um aplicação baseado no material-design.

Dentro colocamos um Scaffold. Ele tem como base o título, ou AppBar, e uma área para o conteúdo, mas conforme forem aprendendo mais, verão que ele vai além disso.

No nosso Scaffold colocamos um texto como título e no corpo também, apenas um elemento texto.


Tplnote Bulbgraph.png

Cuidado com as vírgulas: Para que nosso código fique formatado bonitinho, conforme apresentado acima, precisamos tomar cuidado com as vírgulas. Nem sempre é obrigatório, mas mesmo assim terminamos um elemento e colocamos vírgula pra que o código fique bem formatado.

Uma coisa legal é deixamos nosso main mais limpo e criarmos nossa aplicação em outro arquivo. Na verdade é sempre uma boa metodologia a modularização pela separação dos arquivos.

Vamos criar um arquivo app.dart dentro da pasta lib e colocar o seguinte código:

import 'package:flutter/material.dart';

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hello!'),
      ),
      body: const Text('Hello World'),
    );
  }
}

Veja que colocamos parte do código do Hello World aqui. Só que dentro de uma classe StatelessWidget, ou seja, um widget sem estados. Depois vamos trabalhar com uma classse com estados, mas vamos nessa agora. É necessário implementar um método e fazer um return nele. Alí colocamos o código.

Já o main.dart vai ficar mais simples:

import 'package:flutter/material.dart';
import 'app.dart';

void main() => runApp(const MaterialApp(home: App()));

Veja que importamos o arquivo app.dart criado que está na mesma pasta e colocamos no lugar do código retirado a chamada à nova classe chamada App que criamos.

Então qualquer elemento, que possui um conjunto de elementos também pode ser modularizado. Vamos organizando melhor nosso código em partes para não ficar muito extenso.

Estrutura do Projeto

Agora vamos voltar a estrutura do projeto. Vamos ver cada um dos ítens que temos de pastas e arquivos:

  • .idea/: criada para configurações das ferramentas do Android Studio, caso você o use como IDE.
  • android/, ios/, linux/, macos/, web/ e windows/: possui arquivos para gerar o pacote do aplicativo dessas plataformas.
  • build/: build do projeto em Dart gerado quando rodarmos o comando flutter run.
  • test/: pasta para os testes da aplicação,
  • .gitignore: contém alguns arquivos para serem ignorados na hora de fazer os commits com o git
  • .metadata: usado pelo flutter para gerenciar alguns recursos internos (não mexa nesse arquivo manualmente).
  • pubspec.yml: arquivo para gerenciar as dependências de um projeto Dart.
  • .packages: arquivo de mapeamento das bibliotecas de sistema para os imports do projeto. Ele é gerado automaticamente sempre que uma biblioteca é instalada.
  • helloworld.iml: arquivo criado para facilitar algumas integrações com o IntelliJ.
  • pubspeck.lock: arquivo usado para gerenciar as versões das libs que estão sendo utilizandos.
  • README.MD: arquivo usado para colocar informações sobre o projeto. Usado pelo git.
  • lib/: Pasta usada para colocar os códigos da aplicação.

Anatomia

O Flutter é baseado na construção de uma estrutura hierárquica baseada em widgets, então trabalhamos com esses blocos, montando como se fosse lego e as pecinhas são os widgets. Vamos seguir a estrutura abaixo:

Flutter anatomy scheme.png


Tplnote Bulbgraph.png

Antes precisava do Container, conforme imagem acima. Agora não precisa mais e usamos direto Column.

Primeiro vamos colocar uma imagem no projeto para usarmos. Escolham uma imagem quadrada que quiserem e colocem em uma nova pasta criada na raíz do projeto chamada images. Eu peguei uma imagem da Arisa chamada arisa.png

Agora vamos precisar referenciá-la no arquivo pubspec.yaml.

Abra o arquivo e procure por assets.

# assets:

Descomente e coloque o link da imagem. Algo como:

assets:
  - images/arisa.png

Salve o arquivo e feche.

Depois de editar o arquivo pubspec.yaml utilize o comando abaixo para atualizar o projeto:

flutter pub get

Agora podemos criar nosso programa:

Com base no esquema acima, vemos um Scanffold, um widget que nos dá uma tela em branco.

Dentro dele começamos a construir alguns componentes. O primeiro elemento do Scanffold é AppBar que fica no topo e um Container. O container é um widget onde colocamos o conteúdo do aplicativo.

Dentro do Container colocamos um Column. Os elementos dentro do Column ficão ali organizados em pilha verticalmente. O primeiro elemento dentro do Column é uma imagem e depoi suma Row. Na Row, podemos organizar os elementos horizontalmente. Alí colocamos dois elementos tipo Text e abaixo da Row colocamos um TextField

main.dart

import 'package:flutter/material.dart';
import 'app.dart';

void main() {
  runApp(const MaterialApp(
    home: App(),
  ));
}

app.dart

import 'package:flutter/material.dart';

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Hello!')),
      body: const Column(
        children: [
          Center(
            child: Image(image: AssetImage('images/arisa.png'), width: 300),
          ),
          Row(children: [Text('Name: '), Text('Arisa')]),
          TextField(),
        ],
      ),
    );
  }
}
Flutter anatomy ux.png

Um exemplo um pouco mais prático

Vamos fazer um exemplo básico em que temos dois campos texto onde digitamos o nome, no primeiro, o sobrenome no segundo e um botão para concatenar os dois campos e colocar o conteúdo em um terceiro, não editável. Segue o código:

import 'package:flutter/material.dart';

class App extends StatefulWidget {
  const App({super.key});

  @override
  State<App> createState() => _AppState();
}

class _AppState extends State<App> {
  final TextEditingController _name = TextEditingController();
  final TextEditingController _surname = TextEditingController();
  final TextEditingController _fullname = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Concatenação!')),
      body: Column(
        children: [
          TextField(
            style: const TextStyle(fontSize: 25, color: Colors.green),
            decoration: const InputDecoration(labelText: 'Digite o seu nome'),
            // Para campos tipo senha usar
            // obscureText: true,

            // onChange - chamado a cada interacao
            // onSubmitted so quando termina de digitar
            onChanged: (String texto) {
              print('valor digitado $texto');
            },
            controller: _name,
          ),
          TextField(
            style: const TextStyle(fontSize: 25, color: Colors.green),
            decoration: const InputDecoration(
              labelText: 'Digite o seu sobrenome',
            ),
            controller: _surname,
          ),
          ElevatedButton(
            child: const Text('Concatenar'),
            onPressed: () {
              _fullname.text = '${_name.text} ${_surname.text}';
            },
          ),
          TextField(
            style: const TextStyle(fontSize: 25, color: Colors.green),
            enabled: false,
            controller: _fullname,
          ),
        ],
      ),
    );
  }
}
Flutter anatomy ux2.png

Ok, mas porque esse exemplo usa StatefullWidget?

Stateless: Um widget que não tem seu estado alterado. Um texto, é um widget que não tem seu estado alterado. Stateful: Um widget que tem seu estado alterado. Um switch, é um widget que tem seu estado alterado.

Antes tínhamos trabalhado com widgets sem estado. Mas para construir experiências mais complexas como reagir de maneiras mais interessantes à entrada do usuário, por exemplo, os aplicativos precisam carregar algum estado. O Flutter usa os StatefulWidgets para capturar trabalhar com isso. Os StatefulWidgets são widgets especiais que sabem como gerar objetos que mantém estados.

Mais informações sobre isso em: https://www.flutterparainiciantes.com.br/basico/stateless-stateful

Atividades

Desafio 1 (individual)

Instalar o ambiente de desenvolvimento e seguir passo a passo os exemplos da aula, implementando-os e fazendo funcionar

Desafio 2

Individual ou em Grupo de até 4 pessoas.

Crie um formulário com mais informações e um botão de enviar. Quando clicado, mostre na tela apenas um texto montado com as informações do formulário.