Introdução ao desenvolvimento mobile com Flutter
1. O que é Flutter e por que utilizá-lo?
Flutter é um framework de código aberto criado pelo Google e lançado oficialmente em 2017 para desenvolvimento de aplicativos mobile multiplataforma. Diferente de soluções que utilizam pontes JavaScript, Flutter compila diretamente para código nativo usando o motor gráfico Skia, garantindo desempenho próximo ao de aplicativos desenvolvidos com SDKs nativos.
Os principais diferenciais do Flutter incluem:
- Hot Reload: permite visualizar alterações no código em menos de um segundo, sem perder o estado atual do aplicativo
- Código único: uma base de código para Android, iOS e, recentemente, Web e Desktop
- Desempenho nativo: compilação para código de máquina, sem interpretadores intermediários
- Widgets personalizáveis: interface totalmente customizável sem depender de componentes nativos do sistema
Comparado ao React Native, Flutter oferece maior controle sobre a renderização e desempenho mais consistente. Já em relação ao Xamarin, o Flutter possui uma curva de aprendizado mais suave e documentação mais acessível.
2. Configuração do ambiente de desenvolvimento
Para iniciar com Flutter, siga os passos abaixo:
# Baixe o Flutter SDK em https://flutter.dev
# Extraia o arquivo em ~/development/flutter
# Configure o PATH no arquivo ~/.bashrc ou ~/.zshrc
export PATH="$PATH:$HOME/development/flutter/bin"
# Verifique a instalação
flutter doctor
O comando flutter doctor verifica se todos os componentes estão instalados corretamente: SDK Flutter, Android Studio, Xcode (para iOS), emuladores e conectividade com dispositivos.
Editores recomendados:
- VS Code: leve, com extensão oficial Flutter
- Android Studio: suporte completo para emuladores e depuração
- IntelliJ IDEA: similar ao Android Studio, mas mais genérico
Para testar, configure um emulador Android via Android Studio AVD Manager ou utilize um dispositivo físico com modo desenvolvedor ativado.
3. Estrutura de um projeto Flutter
Ao criar um projeto com flutter create meu_app, a estrutura gerada inclui:
meu_app/
lib/
main.dart # Ponto de entrada do aplicativo
android/ # Configurações específicas do Android
ios/ # Configurações específicas do iOS
test/ # Testes unitários e de widget
pubspec.yaml # Gerenciamento de dependências e assets
O arquivo pubspec.yaml é fundamental:
name: meu_app
description: Um aplicativo Flutter de exemplo
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.1.0 # Pacote para requisições HTTP
provider: ^6.0.0 # Gerenciamento de estado
flutter:
assets:
- assets/images/ # Diretório de imagens
O main.dart inicializa o aplicativo:
import 'package:flutter/material.dart';
void main() {
runApp(const MeuApp());
}
class MeuApp extends StatelessWidget {
const MeuApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Meu App Flutter',
home: const TelaInicial(),
);
}
}
4. Widgets: a base da interface em Flutter
No Flutter, tudo é widget. Cada elemento visual, desde um simples texto até layouts complexos, é representado por um widget.
Widgets Stateless vs Stateful:
- StatelessWidget: imutável, não mantém estado interno. Usado para componentes que não mudam após a construção.
- StatefulWidget: mutável, mantém estado que pode ser alterado durante a execução.
Exemplo de widgets comuns:
import 'package:flutter/material.dart';
class ExemploWidgets extends StatelessWidget {
const ExemploWidgets({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Exemplo de Widgets')),
body: Center(
child: Container(
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8.0),
),
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Texto estilizado', style: TextStyle(fontSize: 20)),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.star, color: Colors.yellow),
SizedBox(width: 8),
Text('Avaliação: 5.0'),
],
),
],
),
),
),
);
}
}
5. Gerenciamento de estado no Flutter
O gerenciamento de estado é crucial para aplicativos dinâmicos. O StatefulWidget oferece controle básico:
class ContadorWidget extends StatefulWidget {
const ContadorWidget({super.key});
@override
State<ContadorWidget> createState() => _ContadorWidgetState();
}
class _ContadorWidgetState extends State<ContadorWidget> {
int _contador = 0;
@override
void initState() {
super.initState();
// Inicialização de recursos
}
void _incrementar() {
setState(() {
_contador++;
});
}
@override
void dispose() {
// Limpeza de recursos
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Contador: $_contador'),
ElevatedButton(
onPressed: _incrementar,
child: const Text('Incrementar'),
),
],
);
}
}
Para projetos maiores, utilize Provider com ChangeNotifier:
class ContadorModel extends ChangeNotifier {
int _valor = 0;
int get valor => _valor;
void incrementar() {
_valor++;
notifyListeners();
}
}
Quando o aplicativo crescer, considere migrar para Bloc (para fluxos complexos) ou Riverpod (mais moderno e seguro).
6. Navegação e roteamento entre telas
A navegação básica utiliza Navigator:
// Navegar para nova tela
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SegundaTela()),
);
// Retornar à tela anterior
Navigator.pop(context);
Para passar parâmetros:
// Na tela de origem
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetalhesTela(item: itemSelecionado),
),
);
// Na tela de destino
class DetalhesTela extends StatelessWidget {
final Item item;
const DetalhesTela({super.key, required this.item});
// ...
}
Roteamento nomeado com onGenerateRoute:
MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == '/detalhes') {
final item = settings.arguments as Item;
return MaterialPageRoute(
builder: (context) => DetalhesTela(item: item),
);
}
return MaterialPageRoute(builder: (context) => const TelaInicial());
},
);
7. Consumo de APIs e persistência local
Para consumir APIs REST, utilize o pacote http:
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<List<Usuario>> buscarUsuarios() async {
final response = await http.get(
Uri.parse('https://jsonplaceholder.typicode.com/users'),
);
if (response.statusCode == 200) {
List<dynamic> dados = json.decode(response.body);
return dados.map((json) => Usuario.fromJson(json)).toList();
} else {
throw Exception('Falha ao carregar usuários');
}
}
class Usuario {
final int id;
final String nome;
final String email;
Usuario({required this.id, required this.nome, required this.email});
factory Usuario.fromJson(Map<String, dynamic> json) {
return Usuario(
id: json['id'],
nome: json['name'],
email: json['email'],
);
}
}
Para persistência local:
import 'package:shared_preferences/shared_preferences.dart';
Future<void> salvarPreferencia() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('nome_usuario', 'João');
}
Future<String?> carregarPreferencia() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('nome_usuario');
}
Para dados mais complexos, utilize sqflite para bancos SQLite.
8. Publicação e próximos passos
Para publicar seu aplicativo:
- Configurar ícones e splash screen: utilize o pacote
flutter_launcher_icons - Assinar o aplicativo: gere keystore para Android e configure perfis de distribuição para iOS
- Gerar APK:
flutter build apk --release - Gerar IPA:
flutter build ios --release
Recursos para aprofundamento:
- Documentação oficial do Flutter
- Cursos na plataforma Dart Academy
- Comunidades no Discord e Stack Overflow
O Flutter continua evoluindo rapidamente, com suporte crescente para Web, Desktop e plataformas embarcadas. Dominar seus fundamentos abre portas para desenvolvimento multiplataforma eficiente e de alta qualidade.
Referências
- Documentação oficial do Flutter — Guia completo com tutoriais, referência de widgets e boas práticas
- Pacote http para Dart — Documentação do pacote oficial para requisições HTTP
- Provider: gerenciamento de estado — Pacote recomendado pelo Google para gerenciamento de estado
- Curso gratuito de Flutter no YouTube (Flutter Brasil) — Canal com tutoriais em português sobre desenvolvimento Flutter
- Shared Preferences no Flutter — Documentação do pacote para persistência simples de dados
- Dart Academy — Cursos e artigos avançados sobre Dart e Flutter
- Stack Overflow - Flutter — Comunidade ativa para dúvidas técnicas sobre Flutter