container를 이용해 위젯을 생성하고 꾸밀 때 decoration속성으로는 분명히 한계가 있는데 이럴때 사용하면 좋다.
프로그래밍을 처음 배울 때 Java를 배웠는데 그때 이런게 있다라고 잠깐 접했었는데 그 때의 기억과 거의 비슷하다.
CustomPaint(
painter: MyPainter(),
foregroundPainter: MyForegroundPainter(),
size: const Size(100,100),
child: Container()
)
Container의 decoration속성과 비슷하다고 볼 수 있는 painter속성과 child위에 그려지는 foregroundPainter속성이 주요 속성이된다.
size속성은 child 위젯 혹은 상위 위젯의 크기에 맞춰지게 되는데 child가 없다면 size속성은 null이 아니어야 한다.
class MyPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
painter와 forgroundPainter속성의 타입은 CustomPainter이고 CustomPainter를 상속받는 클래스를 생성해서 사용한다.
CustomPainter를 상속받는 클래스를 만들면 paint, shouldRepaint메소드를 구현해야한다. 후자는 해당 클래스가 다시 그려질 수 있는지를 반환한다. 페인터가 실시간으로 변경될 필요가 있다면 true를 반환하면 되는데 paint로직이 복잡하면 프레임이 떨어지기도 하기 때문에 주의 해야한다.
Container(
width: 200,
height: 200,
color: Colors.amber,
child: CustomPaint(
painter: MyPainter(),
// foregroundPainter: MyForegroundPainter(),
),
)
class MyPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..strokeWidth = 3
..color = Colors.black
..style = ui.PaintingStyle.stroke;
final path = Path()
..moveTo(0, 50)
..lineTo(0, 100);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
paint는 그림을 그리는 페인트라 생각하면 된다. 붓의 색이나 두께 스타일등을 지정할 수 있고 path는 어떻게 그릴지를 지정하게 된다.
path변수의 가장 초기 (x,y)좌표는 (0,0)이고 최대 값은 CustomPaint의 size속성 혹은 child의 (width, height)를 따라간다.
그 후 캔버스에 그림을 그리는 식으로 사용하게 된다.
(0, 50)으로 시작점을 이동 한 후 (0, 100)까지 검은색의 두께가 10인 선이 그려졌다.
final path = Path()
..moveTo(0, 50)
..lineTo(0, 100)
..lineTo(200, 100)
..lineTo(200, 50)
..lineTo(0, 50);
final paint = Paint()
..strokeWidth = 10
..color = Colors.black
..style = ui.PaintingStyle.fill;
페인트의 style속성을 PaintingStyle.fill 바꾸게 될 경우
필자는 곡선 표현이 필요해서 CustomPaint를 쓰게 됐다.
이미지 출처 : wikipedia
final path = Path()
..moveTo(0, 50)
..lineTo(0, 100)
..quadraticBezierTo(0, 150, 50, 150);
이미지에서 P0좌표가 lineTo를 이용해 마지막으로 이동한 좌표(0, 100)이 되고 quadraticBezierTo메소드의 인자 중 처음 두 개는 제어점 P1 뒤의 두 개는 이동점 P2가 된다.
이런식으로 곡선을 그릴 수 있다.