Flutter Painting Widgets: Custom Drawing
•7 min read
Painting widgets are essential for creating custom drawings and visual effects in Flutter applications. Let's explore the various painting widgets and how to use them effectively.
1. Basic Painting Widgets
CustomPaint
class CustomPaintExample extends StatelessWidget { @override Widget build(BuildContext context) { return CustomPaint( size: Size(200, 200), painter: MyPainter(), ); } } class MyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.blue ..style = PaintingStyle.fill; final path = Path() ..moveTo(0, size.height) ..lineTo(size.width / 2, 0) ..lineTo(size.width, size.height) ..close(); canvas.drawPath(path, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }
RepaintBoundary
class RepaintBoundaryExample extends StatefulWidget { @override _RepaintBoundaryExampleState createState() => _RepaintBoundaryExampleState(); } class _RepaintBoundaryExampleState extends State<RepaintBoundaryExample> { int _counter = 0; @override Widget build(BuildContext context) { return Column( children: [ RepaintBoundary( child: CustomPaint( size: Size(200, 200), painter: MyPainter(), ), ), SizedBox(height: 20), ElevatedButton( onPressed: () { setState(() { _counter++; }); }, child: Text('Counter: $_counter'), ), ], ); } }
2. Advanced Painting Widgets
ShaderMask
class ShaderMaskExample extends StatelessWidget { @override Widget build(BuildContext context) { return ShaderMask( shaderCallback: (bounds) => LinearGradient( colors: [Colors.red, Colors.blue], begin: Alignment.topLeft, end: Alignment.bottomRight, ).createShader(bounds), child: Container( width: 200, height: 200, color: Colors.white, child: Center( child: Text( 'Gradient Text', style: TextStyle( fontSize: 24, color: Colors.white, ), ), ), ), ); } }
BackdropFilter
class BackdropFilterExample extends StatelessWidget { @override Widget build(BuildContext context) { return Stack( children: [ Container( width: 200, height: 200, color: Colors.blue, ), BackdropFilter( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: Container( width: 200, height: 200, color: Colors.white.withOpacity(0.1), child: Center( child: Text( 'Blur Effect', style: TextStyle( fontSize: 24, color: Colors.white, ), ), ), ), ), ], ); } }
3. Custom Painting Widgets
Custom Gradient Painter
class CustomGradientPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final rect = Rect.fromLTWH(0, 0, size.width, size.height); final gradient = LinearGradient( colors: [Colors.red, Colors.orange, Colors.yellow], begin: Alignment.topLeft, end: Alignment.bottomRight, ); final paint = Paint() ..shader = gradient.createShader(rect) ..style = PaintingStyle.fill; canvas.drawRect(rect, paint); } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }
Custom Pattern Painter
class CustomPatternPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.blue ..style = PaintingStyle.stroke ..strokeWidth = 2; for (var i = 0; i < size.width; i += 20) { for (var j = 0; j < size.height; j += 20) { canvas.drawCircle(Offset(i.toDouble(), j.toDouble()), 5, paint); } } } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }
4. Best Practices
-
Implement proper painting
- Choose appropriate painting widgets
- Handle painting states
- Consider performance impact
-
Enhance painting experience
- Add smooth transitions
- Implement proper effects
- Consider visual feedback
-
Optimize painting performance
- Use const constructors
- Minimize repaints
- Handle memory efficiently
By mastering these painting widgets and following best practices, you can create Flutter applications that are:
- More visually appealing
- More dynamic
- More efficient
- More maintainable