Explorando o Custom Painter no Flutter para Desenhos Personalizados
Introdução
O Flutter é conhecido por sua flexibilidade em criar interfaces personalizadas. Uma das ferramentas mais poderosas para isso é o Custom Painter, que permite desenhar diretamente no canvas, criando formas, animações e gráficos completamente personalizados.
Neste tutorial, vamos explorar como usar o CustomPainter
para criar desenhos personalizados no Flutter, abordando cenários práticos e dicas avançadas.
—
1. O que é o CustomPainter?
O CustomPainter
é uma classe abstrata que permite implementar métodos como paint
para desenhar diretamente no canvas, usando objetos como Paint
, Path
e Canvas
. Ele é usado para criar gráficos vetoriais, animações e muito mais.
—
2. Criando um Custom Painter Básico
Vamos começar com um exemplo básico de como desenhar um círculo:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Custom Painter Example')),
body: Center(
child: CustomPaint(
size: const Size(200, 200),
painter: CirclePainter(),
),
),
),
);
}
}
class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
size.width / 2,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
O código acima desenha um círculo azul preenchido no centro do canvas.
—
3. Adicionando Complexidade com Path
Você pode criar formas complexas com o Path
. Aqui está um exemplo de como desenhar uma estrela:
class StarPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.orange
..style = PaintingStyle.fill;
final path = Path();
path.moveTo(size.width / 2, 0);
path.lineTo(size.width * 0.4, size.height * 0.6);
path.lineTo(0, size.height * 0.6);
path.lineTo(size.width * 0.3, size.height);
path.lineTo(size.width * 0.2, size.height * 1.4);
path.lineTo(size.width / 2, size.height * 1.1);
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
—
4. Animações com Custom Painter
Você pode usar o CustomPainter
com animações para criar gráficos dinâmicos. Aqui está um exemplo de como animar um círculo:
class AnimatedCircle extends StatefulWidget {
@override
_AnimatedCircleState createState() => _AnimatedCircleState();
}
class _AnimatedCircleState extends State
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(reverse: true);
_animation = Tween(begin: 50, end: 150).animate(_controller);
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return CustomPaint(
size: const Size(200, 200),
painter: AnimatedCirclePainter(radius: _animation.value),
);
},
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class AnimatedCirclePainter extends CustomPainter {
final double radius;
AnimatedCirclePainter({required this.radius});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.red
..style = PaintingStyle.fill;
canvas.drawCircle(
Offset(size.width / 2, size.height / 2),
radius,
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
—
5. Dicas e Boas Práticas
- Use
shouldRepaint
com sabedoria para otimizar o desempenho. - Divida sua lógica de desenho em funções reutilizáveis.
- Evite cálculos caros dentro do método
paint
.
Publicar comentário