Flutter é um framework de desenvolvimento de aplicativos móveis criado pelo Google em 2017. Ele é baseado em Dart, uma linguagem de programação própria do Google, e é utilizado para criar aplicativos para Android e iOS de forma rápida e eficiente.
Antes de começar a programar em Flutter, é importante ter algum conhecimento em programação e em alguma linguagem de programação, como Java ou Python. Também é recomendável ter algum conhecimento básico sobre a estrutura de um aplicativo móvel e suas funcionalidades.
Instalando o Flutter
Para começar a programar em Flutter, é necessário instalar o framework em sua máquina. A instalação do Flutter é simples e pode ser feita seguindo os passos descritos na documentação oficial.
Depois de instalar o Flutter, é importante verificar se a instalação foi bem-sucedida. Para isso, basta abrir o terminal e digitar o comando flutter doctor
. Esse comando verificará se todas as dependências necessárias para o funcionamento do Flutter estão instaladas e funcionando corretamente.
Criando um projeto em Flutter
Para criar um novo projeto em Flutter, basta abrir o terminal e digitar o comando flutter create nome_do_projeto
. Isso criará uma nova pasta com o nome do projeto e toda a estrutura básica de um projeto em Flutter.
A estrutura básica de um projeto em Flutter inclui os seguintes arquivos e pastas:
pubspec.yaml
: arquivo de configuração do projeto, onde são especificadas as dependências e configurações do projeto.lib
: pasta onde ficam os arquivos de código-fonte do projeto.test
: pasta onde ficam os arquivos de teste do projeto.
Estrutura básica de um aplicativo em Flutter
Um aplicativo em Flutter é composto por uma árvore de widgets. Cada widget é responsável por exibir algum elemento na tela do aplicativo, como texto, imagem ou botão.
A estrutura básica de um aplicativo em Flutter é composta pelos seguintes widgets:
MaterialApp
: widget principal do aplicativo, responsável por configurar o tema e a navegation do aplicativo.Scaffold
: widget que fornece uma estrutura básica para a interface do aplicativo, incluindo uma barra de título e uma barra de navegação inferior (opcional).AppBar
: widget que exibe a barra de título do aplicativo.Body
: widget que exibe o conteúdo principal da tela do aplicativo.- A seguir, veja um exemplo de como esses widgets podem ser utilizados para criar uma tela básica de um aplicativo em Flutter:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Meu aplicativo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Tela inicial'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Você clicou o botão abaixo:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Incrementar',
child: Icon(Icons.add),
),
);
}
}
Neste exemplo, a tela principal do aplicativo é exibida pelo widget Scaffold
, que possui uma barra de título exibida pelo widget AppBar
e um corpo exibido pelo widget Body
. O corpo da tela exibe um contador que é incrementado ao clicar no botão flutuante exibido pelo widget FloatingActionButton
.
Gerenciamento de estado em Flutter
Um dos principais desafios na programação de aplicativos móveis é o gerenciamento do estado da aplicação. O estado de uma aplicação é a informação que é exibida e manipulada pelo aplicativo. Por exemplo, no exemplo anterior, o contador é um exemplo de estado da aplicação.
Em Flutter, existem duas formas principais de gerenciar o estado de uma aplicação: StatefulWidget
e Bloc
.
StatefulWidget
Um StatefulWidget
é um widget que possui estado interno e pode ser atualizado pelo aplicativo. Quando o estado de um StatefulWidget
é alterado, o widget é redesenhado na tela.
Para criar um StatefulWidget
, é necessário criar uma classe que estende de StatefulWidget
e uma classe interna que estende de State
. A classe interna é responsável por gerenciar o estado do widget e possui o método build
, que é chamado sempre que o estado do widget é alterado.
Veja o exemplo abaixo, que exibe um contador como um StatefulWidget
:
class MyCounter extends StatefulWidget {
@override
_MyCounterState createState() => _MyCounterState();
}
class _MyCounterState extends State<MyCounter> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(
'Você clicou o botão abaixo:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
);
}
}
Bloc
O Bloc
(Business Logic Component) é um padrão de projeto que separa a lógica de negócios da interface de usuário de um aplicativo. Ele é utilizado para gerenciar o estado de um aplicativo de forma mais escalável e testável.
Para utilizar o Bloc
em um aplicativo Flutter, é necessário instalar o pacote flutter_bloc
. Depois disso, é preciso criar uma classe que estende de Bloc
e define os eventos e estados da aplicação.
Veja o exemplo abaixo, que exibe um contador como um Bloc
:
import 'package:flutter_bloc/flutter_bloc.dart';
enum CounterEvent { increment }
class CounterBloc extends Bloc<CounterEvent, int> {
@override
int get initialState => 0;
@override
Stream<int> mapEventToState(CounterEvent event) async* {
switch (event) {
case CounterEvent.increment:
yield state + 1;
break;
}
}
}
Para exibir o estado do contador gerenciado pelo Bloc
, é necessário utilizar o widget BlocBuilder
. O BlocBuilder
é um widget que atualiza a interface de usuário sempre que o estado do Bloc
é alterado.
Veja o exemplo abaixo, que exibe o contador gerenciado pelo Bloc
em uma tela:
import 'package:flutter/material.dart';
import 'package:meu_aplicativo/counter_bloc.dart';
class MyCounterPage extends StatelessWidget {
final CounterBloc _counterBloc = CounterBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Contador com Bloc'),
),
body: BlocBuilder(
bloc: _counterBloc,
builder: (context, count) {
return Center(
child: Text(
'$count',
style: TextStyle(fontSize: 24.0),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_counterBloc.add(CounterEvent.increment);
},
child: Icon(Icons.add),
),
);
}
}
Testando um aplicativo em Flutter
É importante testar um aplicativo para garantir que ele esteja funcionando corretamente e para evitar erros em sua execução. Em Flutter, existem duas formas principais de testar um aplicativo: testes unitários e testes de interface de usuário.
Testes unitários
Os testes unitários são utilizados para testar uma pequena parte do código de um aplicativo, geralmente uma função ou uma classe. Eles são úteis para garantir que o código está funcionando corretamente e para evitar erros de regressão.
Para criar testes unitários em Flutter, é necessário adicionar os seguintes arquivos à pasta test
do projeto:
test_driver
: arquivo que contém os testes que serão executados no dispositivo ou emulador.test_driver/main.dart
: arquivo que inicia os testes.
Veja o exemplo abaixo, que testa a função add
de uma classe Calculator
:
import 'package:test/test.dart';
import 'package:meu_aplicativo/calculator.dart';
void main() {
test('calculator test', () {
expect(Calculator().add(2, 3), 5);
});
}
Para executar os testes unitários, basta abrir o terminal e digitar o comando flutter test
.
Testes de interface de usuário
Os testes de interface de usuário são utilizados para testar a interface de usuário de um aplicativo e garantir que ela esteja funcionando corretamente. Eles são úteis para garantir a qualidade do aplicativo e para evitar erros de regressão.
Para criar testes de interface de usuário em Flutter, é necessário adicionar os seguintes arquivos à pasta test_driver
do projeto:
app_test.dart
: arquivo que contém os testes que serão executados no dispositivo ou emulador.
Veja o exemplo abaixo, que testa se o título da tela principal do aplicativo está sendo exibido corretamente:
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('Meu aplicativo', () {
FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() async {
if (driver != null) {
driver.close();
}
});
test('exibe título da tela principal', () async {
expect(await driver.getText(find.text('Tela principal')), 'Tela principal');
});
});
}
Para executar os testes de interface de usuário, basta abrir o terminal e digitar o comando flutter drive --target=test_driver/app_test.dart
.
Publicando um aplicativo em Flutter
Para publicar um aplicativo em Flutter, é necessário seguir os passos descritos na documentação oficial.
Em resumo, é preciso criar uma conta na Play Store e na App Store e seguir as instruções para publicar o aplicativo nos respectivos marketplaces.
Antes de publicar o aplicativo, é importante testá-lo em dispositivos reais e em diferentes resoluções de tela para garantir que ele esteja funcionando corretamente. Além disso, é recomendável otimizar o aplicativo para melhorar seu desempenho e reduzir seu tamanho.