Custom painters let you draw shapes, lines, and designs directly on the screen. This helps you create unique visuals that normal widgets can't do.
0
0
Custom painters (CustomPaint) in Flutter
Introduction
When you want to draw a simple shape like a circle or rectangle with custom colors.
When you need to create a graph or chart that updates dynamically.
When you want to design a custom background or pattern for your app screen.
When you want to draw animations or effects that are not available as widgets.
Syntax
Flutter
class MyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { // Drawing code here } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return false; } } // Use in widget tree: CustomPaint( painter: MyPainter(), child: Container(width: 100, height: 100), )
The paint method is where you draw on the canvas.
The shouldRepaint method tells Flutter when to redraw.
Examples
This draws a blue circle centered inside a 100x100 box.
Flutter
class CirclePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = Colors.blue; canvas.drawCircle(size.center(Offset.zero), 40, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; } CustomPaint( painter: CirclePainter(), child: SizedBox(width: 100, height: 100), )
This draws a red diagonal line from top-left to bottom-right.
Flutter
class LinePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.red ..strokeWidth = 4; canvas.drawLine(Offset(0, 0), Offset(size.width, size.height), paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; } CustomPaint( painter: LinePainter(), child: SizedBox(width: 100, height: 100), )
Sample App
This app draws a simple yellow smiley face with black eyes and a smile using CustomPaint.
Flutter
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('CustomPaint Example')), body: Center( child: CustomPaint( size: const Size(150, 150), painter: SmileyPainter(), ), ), ), ); } } class SmileyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint()..color = Colors.yellow; canvas.drawCircle(size.center(Offset.zero), size.width / 2, paint); final eyePaint = Paint()..color = Colors.black; canvas.drawCircle(Offset(size.width * 0.35, size.height * 0.35), 10, eyePaint); canvas.drawCircle(Offset(size.width * 0.65, size.height * 0.35), 10, eyePaint); final smilePaint = Paint() ..color = Colors.black ..style = PaintingStyle.stroke ..strokeWidth = 5; final smilePath = Path(); smilePath.moveTo(size.width * 0.3, size.height * 0.65); smilePath.quadraticBezierTo(size.width * 0.5, size.height * 0.85, size.width * 0.7, size.height * 0.65); canvas.drawPath(smilePath, smilePaint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }
OutputSuccess
Important Notes
Always set shouldRepaint to false if your drawing does not change to improve performance.
Use canvas methods like drawCircle, drawRect, and drawPath to create shapes.
CustomPaint size can be set by its size property or by its child widget size.
Summary
Custom painters let you draw directly on the screen for unique visuals.
Implement paint to draw and shouldRepaint to control redrawing.
Use CustomPaint widget to add your painter to the widget tree.