CustomPaint
는 Flutter에서 사용자 정의 그래픽을 그릴 수 있는 강력한 위젯입니다. CustomPaint
는 다양한 형태와 복잡한 그래픽을 그릴 수 있는 기능을 제공하며, 이를 통해 Flutter의 기본 위젯으로는 구현하기 어려운 복잡한 UI를 만들 수 있습니다.
1. CustomPaint
의 개요
CustomPaint
는 CustomPainter
를 사용하여 사용자 정의 그래픽을 그릴 수 있는 위젯입니다. 이 위젯은 paint
메서드를 통해 자신의 그래픽을 그리는 방식으로 작동하며, 이를 통해 Flutter에서 다양한 형태의 그래픽을 효율적으로 처리할 수 있습니다.
2. 주요 구성 요소
2.1. CustomPaint
위젯
painter
:CustomPainter
를 설정하여 그래픽을 그리는 데 사용됩니다.child
:CustomPaint
위젯의 자식 위젯으로, 그래픽이 그려지는 영역 위에 배치됩니다.
CustomPaint(
painter: MyCustomPainter(),
child: Container(
width: 200,
height: 200,
child: Center(child: Text('Custom Paint')),
),
)
2.2. CustomPainter
클래스
CustomPainter
는 paint
메서드와 shouldRepaint
메서드를 구현하여 사용자의 그래픽을 그립니다.
paint(Canvas canvas, Size size)
: 실제로 그래픽을 그리는 메서드입니다.Canvas
객체를 사용하여 다양한 그래픽을 그릴 수 있습니다.shouldRepaint(CustomPainter oldDelegate)
: 이 메서드는 이전CustomPainter
와 현재CustomPainter
가 같으면false
를 반환하고, 다르면true
를 반환하여 애니메이션 등의 업데이트가 필요할 때를 결정합니다.
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.stroke
..strokeWidth = 5;
// Draw a rectangle
canvas.drawRect(Rect.fromLTWH(20, 20, 100, 100), paint);
// Draw a circle
paint.color = Colors.red;
canvas.drawCircle(Offset(150, 150), 50, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
3. 사용 예제
3.1. 기본 사용법
아래는 간단한 CustomPainter
를 사용하여 직사각형과 원을 그리는 예제입니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('CustomPaint Example')),
body: Center(
child: CustomPaint(
size: Size(200, 200),
painter: MyCustomPainter(),
),
),
),
);
}
}
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.stroke
..strokeWidth = 5;
// Draw a rectangle
canvas.drawRect(Rect.fromLTWH(20, 20, 100, 100), paint);
// Draw a circle
paint.color = Colors.red;
canvas.drawCircle(Offset(150, 150), 50, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
3.2. 애니메이션과 함께 사용
CustomPainter
는 애니메이션과 결합하여 복잡한 애니메이션 효과를 구현할 수 있습니다. AnimationController
와 함께 사용할 때, shouldRepaint
를 true
로 설정하여 애니메이션이 계속해서 업데이트되도록 할 수 있습니다.
예제 코드:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AnimatedCustomPaint(),
);
}
}
class AnimatedCustomPaint extends StatefulWidget {
@override
_AnimatedCustomPaintState createState() => _AnimatedCustomPaintState();
}
class _AnimatedCustomPaintState extends State<AnimatedCustomPaint> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..repeat(reverse: true);
_animation = Tween<double>(begin: 50, end: 150).animate(_controller);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated CustomPaint')),
body: Center(
child: CustomPaint(
size: Size(200, 200),
painter: AnimatedPainter(_animation.value),
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
class AnimatedPainter extends CustomPainter {
final double radius;
AnimatedPainter(this.radius);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
// Draw a circle with animated radius
canvas.drawCircle(size.center(Offset.zero), radius, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
4. 고급 사용법
4.1. Path 객체 사용
Canvas
클래스의 drawPath
메서드를 사용하여 복잡한 형태를 그릴 수 있습니다. Path
객체를 사용하여 다양한 형태를 정의할 수 있습니다.
예제 코드:
class PathPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.green
..style = PaintingStyle.stroke
..strokeWidth = 3;
final path = Path()
..moveTo(20, 20)
..lineTo(100, 20)
..lineTo(100, 100)
..close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
4.2. 클리핑 및 변형
CustomPainter
는 클리핑 및 변형 기능을 제공하여 복잡한 그래픽 작업을 수행할 수 있습니다.
예제 코드:
class ClipAndTransformPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.orange
..style = PaintingStyle.fill;
final rect = Rect.fromLTWH(20, 20, 150, 150);
canvas.save(); // Save the current state
canvas.clipRect(rect); // Clip the canvas to the rectangle
// Apply a rotation transformation
canvas.rotate(0.1);
// Draw a rectangle
canvas.drawRect(rect, paint);
canvas.restore(); // Restore the saved state
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
5. 요약
CustomPaint
: 사용자 정의 그래픽을 그릴 수 있는 위젯입니다.CustomPainter
: 실제로 그래픽을 그리는 데 사용됩니다.paint
메서드를 구현하여 그래픽을 그리며,shouldRepaint
메서드를 통해 애니메이션이나 상태 변화에 따라 다시 그려야 할지 결정합니다.Canvas
와Paint
:Canvas
는 그래픽을 그리는 기본 도구이며,Paint
는 선, 색상, 스타일 등을 정의합니다.- 애니메이션 및 고급 그래픽:
CustomPaint
와 애니메이션을 결합하여 동적인 UI를 만들 수 있으며, 복잡한 형태와 변형을 통해 정교한 그래픽을 구현할 수 있습니다.
CustomPaint
와 CustomPainter
를 활용하면 Flutter에서 복잡한 그래픽과 애니메이션을 효율적으로 처리할 수 있습니다.