CustomPainterクラスの基本構造
FlutterではCustomPainter抽象クラスを使用して、独自の描画処理を実装することが可能です。このクラスを継承してpaintメソッドを実装することで、複雑なグラフィック表現を実現できます。
シンプルな円の描画例
class CirclePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.green
..strokeWidth = 4.0
..style = PaintingStyle.stroke;
final center = Offset(size.width / 2, size.height / 2);
final radius = 60.0;
canvas.drawCircle(center, radius, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
CustomPaintウィジェットの使用方法
カスタム描画クラスをUIに適用するにはCustomPaintウィジェットを使用します。
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CustomPaint(
painter: CirclePainter(),
child: SizedBox(
width: 150,
height: 150,
),
),
),
);
}
描画プロパティの詳細
painter: 背景描画用のペインターforegroundPainter: 前景描画用のペインターsize: 描画領域のサイズ指定isComplex: 複雑な描画であることを示すフラグwillChange: 描画内容が頻繁に変化することを示すフラグ
アニメーション対応の実装
描画内容をアニメーションで変化させる場合は、Listenableオブジェクトを介して再描画を効率的に制御できます。
class AnimatedPainter extends CustomPainter {
final Animation<double> animation;
AnimatedPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final rect = Rect.fromLTWH(
0,
0,
size.width * animation.value,
size.height * animation.value
);
final paint = Paint()..color = Colors.blue;
canvas.drawRect(rect, paint);
}
@override
bool shouldRepaint(covariant AnimatedPainter oldDelegate) {
return true;
}
}
アニメーションコントローラーの実装
class _AnimationDemoState extends State<AnimationDemo>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 2),
)..forward();
}
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: AnimatedPainter(_controller),
child: SizedBox(width: 200, height: 200),
);
}
}
Canvasの主な描画メソッド
drawLine: 直線描画drawRect: 矩形描画drawCircle: 円描画drawPath: パス描画drawArc: 円弧描画
Paintオブジェクトの設定例
final paint = Paint()
..color = Colors.red
..strokeWidth = 2.0
..isAntiAlias = true
..style = PaintingStyle.fill;