Dart e Flutter: desenvolvimento multiplataforma
1. Introdução ao ecossistema Dart e Flutter
1.1. O que é Dart? Características da linguagem
Dart é uma linguagem de programação moderna, criada pelo Google, projetada para desenvolvimento de aplicações client-side. Suas principais características incluem tipagem forte e opcional, compilação Just-In-Time (JIT) para desenvolvimento com hot reload e Ahead-Of-Time (AOT) para produção, resultando em código nativo rápido. Dart também oferece suporte a programação orientada a objetos, funções de primeira classe e null safety, que elimina erros comuns de referência nula.
// Exemplo de sintaxe Dart com null safety
void main() {
String? nome; // Variável anulável
nome = 'Flutter';
print('Olá, $nome!');
int idade = 30; // Variável não anulável
// idade = null; // Erro de compilação
}
1.2. O que é Flutter? Arquitetura baseada em widgets
Flutter é um framework de código aberto do Google que utiliza Dart para construir interfaces de usuário nativas para múltiplas plataformas. Sua arquitetura é baseada em widgets, onde cada elemento visual é um widget imutável. Flutter possui seu próprio motor de renderização (Skia, sendo substituído por Impeller), que desenha diretamente na tela, garantindo consistência visual entre plataformas.
// Widget básico em Flutter
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Exemplo Flutter')),
body: const Center(child: Text('Olá, Mundo!')),
),
);
}
}
1.3. Vantagens do desenvolvimento multiplataforma com Flutter
Flutter oferece desempenho próximo ao nativo, hot reload para iteração rápida, e uma única base de código para Android, iOS, Web e Desktop. Isso reduz custos de desenvolvimento e manutenção, mantendo alta qualidade visual e funcional.
2. Fundamentos da linguagem Dart para Flutter
2.1. Sintaxe básica: variáveis, funções, classes e null safety
// Classes e null safety
class Pessoa {
final String nome;
int? idade; // Pode ser nulo
Pessoa(this.nome, {this.idade});
void apresentar() {
print('Meu nome é $nome');
if (idade != null) {
print('Tenho $idade anos');
}
}
}
void main() {
var pessoa = Pessoa('Ana', idade: 28);
pessoa.apresentar();
}
2.2. Programação assíncrona: Futures, async/await e Streams
// Exemplo de async/await
Future<String> buscarDados() async {
await Future.delayed(Duration(seconds: 2));
return 'Dados carregados';
}
void main() async {
print('Carregando...');
String resultado = await buscarDados();
print(resultado);
}
2.3. Gerenciamento de dependências e pacotes com pubspec.yaml
# pubspec.yaml
name: meu_app
description: Aplicação Flutter
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.1.0
provider: ^6.0.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
3. Construindo interfaces com Widgets
3.1. Widgets Stateless vs Stateful
// StatelessWidget - imutável
class SaudacaoWidget extends StatelessWidget {
final String nome;
const SaudacaoWidget({super.key, required this.nome});
@override
Widget build(BuildContext context) {
return Text('Olá, $nome!');
}
}
// StatefulWidget - com estado mutável
class ContadorWidget extends StatefulWidget {
const ContadorWidget({super.key});
@override
State<ContadorWidget> createState() => _ContadorWidgetState();
}
class _ContadorWidgetState extends State<ContadorWidget> {
int _contador = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Contagem: $_contador'),
ElevatedButton(
onPressed: () => setState(() => _contador++),
child: const Text('Incrementar'),
),
],
);
}
}
3.2. Layouts fundamentais
// Exemplo de layout com Row e Column
class LayoutExemplo extends StatelessWidget {
const LayoutExemplo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
),
const SizedBox(height: 20),
Expanded(
child: Container(color: Colors.amber),
),
],
),
),
);
}
}
3.3. Navegação entre telas
// Navegação com rotas nomeadas
void main() {
runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/detalhes': (context) => const DetalhesPage(),
},
));
}
// Navegação programática
Navigator.pushNamed(context, '/detalhes');
4. Gerenciamento de estado em aplicações Flutter
4.1. StatefulWidget e setState
// Gerenciamento simples com setState
class ListaTarefas extends StatefulWidget {
@override
State<ListaTarefas> createState() => _ListaTarefasState();
}
class _ListaTarefasState extends State<ListaTarefas> {
final List<String> _tarefas = [];
void _adicionarTarefa(String tarefa) {
setState(() => _tarefas.add(tarefa));
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: _tarefas.length,
itemBuilder: (context, index) => ListTile(
title: Text(_tarefas[index]),
),
);
}
}
4.2. Provider e Riverpod
// Provider para gerenciamento de estado
class ContadorProvider extends ChangeNotifier {
int _contador = 0;
int get contador => _contador;
void incrementar() {
_contador++;
notifyListeners();
}
}
// Uso no widget
class MeuWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final contador = context.watch<ContadorProvider>();
return Text('${contador.contador}');
}
}
4.3. Bloc/Cubit
// Cubit para gerenciamento de estado com streams
class ContadorCubit extends Cubit<int> {
ContadorCubit() : super(0);
void incrementar() => emit(state + 1);
void decrementar() => emit(state - 1);
}
5. Acesso a recursos nativos e APIs do dispositivo
5.1. Plugins e pacotes
// Uso do pacote camera
import 'package:camera/camera.dart';
Future<void> iniciarCamera() async {
final cameras = await availableCameras();
final camera = cameras.first;
// Controlador da câmera
}
5.2. Comunicação com APIs REST
// Requisição HTTP com Dio
import 'package:dio/dio.dart';
Future<Map<String, dynamic>> buscarUsuario(int id) async {
final dio = Dio();
final response = await dio.get('https://api.exemplo.com/usuarios/$id');
return response.data;
}
5.3. Persistência de dados
// SharedPreferences para dados simples
import 'package:shared_preferences/shared_preferences.dart';
Future<void> salvarPreferencia(String chave, String valor) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(chave, valor);
}
6. Testes, depuração e otimização de desempenho
6.1. Testes unitários e de widget
// Teste unitário
import 'package:flutter_test/flutter_test.dart';
void main() {
test('Contador deve incrementar', () {
final contador = Contador();
contador.incrementar();
expect(contador.valor, 1);
});
}
6.2. Ferramentas de depuração
Flutter DevTools oferece inspeção de widgets, timeline de desempenho, análise de memória e rede. Para acessar, execute flutter devtools no terminal.
6.3. Otimização de desempenho
// Evitar rebuilds desnecessários com const
class WidgetOtimizado extends StatelessWidget {
const WidgetOtimizado({super.key});
@override
Widget build(BuildContext context) {
return const Text('Widget constante');
}
}
7. Publicação e deploy multiplataforma
7.1. Configuração para Android
// build.gradle (app-level)
android {
compileSdkVersion 34
defaultConfig {
applicationId "com.exemplo.meuapp"
minSdkVersion 21
targetSdkVersion 34
}
}
7.2. Configuração para iOS
Para iOS, configure o Xcode com certificados de desenvolvimento e distribuição, e utilize o App Store Connect para publicação.
7.3. Publicação para Web e Desktop
// Configuração para web
flutter build web --release
// Configuração para desktop
flutter build windows --release
flutter build macos --release
flutter build linux --release
Referências
- Documentação oficial do Dart — Guia completo da linguagem Dart, incluindo sintaxe, null safety e programação assíncrona
- Documentação oficial do Flutter — Referência principal para desenvolvimento Flutter, com tutoriais, widgets e exemplos práticos
- Pub.dev - Pacotes Dart e Flutter — Repositório oficial de pacotes para Dart e Flutter, incluindo http, provider e shared_preferences
- Flutter DevTools — Ferramentas de depuração e profiling para aplicações Flutter
- Riverpod - Gerenciamento de Estado — Documentação do Riverpod, alternativa moderna ao Provider para gerenciamento de estado
- Bloc Library — Guia completo do padrão Bloc/Cubit para gerenciamento de estado reativo em Flutter
- Flutter Testing Guide — Guia oficial de testes unitários, de widget e de integração no Flutter