I can't make the custom painter repaint. I tried to use Listenable, callbacks, setState and nothing repaints the screen.
The docs says this:
The most efficient way to trigger a repaint is to either:
- Extend this class and supply a repaint argument to the constructor of the CustomPainter, where that object notifies its listeners when it is time to repaint.
- Extend Listenable (e.g. via ChangeNotifier) and implement CustomPainter, so that the object itself provides the notifications directly. In either case, the CustomPaint widget or RenderCustomPaint render object will listen to the Listenable and repaint whenever the animation ticks, avoiding both the build and layout phases of the pipeline.
But the code don't work as intended.
This is the code I'm using:
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(
home: Scaffold(appBar: AppBar(), body: Pad()),
));
}
class Pad extends StatefulWidget {
@override
_PadState createState() => _PadState();
}
class _PadState extends State<Pad> {
@override
Widget build(BuildContext context) {
final painter = Painter();
return GestureDetector(
onTap: () {
setState(() {
painter.addY(10);
});
},
child: CustomPaint(
painter: painter,
child: Container(),
));
}
}
class Painter extends CustomPainter {
double y = 10;
addY(val) {
y += val;
}
@override
void paint(Canvas canvas, Size size) {
canvas.drawCircle(Offset(size.width / 2, y++), 100, Paint());
}
@override
bool shouldRepaint(Painter oldDelegate) {
return true;
}
}
Listenable works just fine, use ValueNotifier for example, see https://github.com/pskink/matrix_gesture_detector/blob/master/example/lib/custom_painter_demo.dart for some sample code
I don't know why but when I add an empty DropdownButtonFormField widget, It worked.
Even shouldRepaint function always return false. The paint function always re-call when tap to GestureDetector.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(
home: Scaffold(appBar: AppBar(), body: const Pad()),
));
}
class Pad extends StatefulWidget {
const Pad({Key? key}) : super(key: key);
@override
_PadState createState() => _PadState();
}
class _PadState extends State<Pad> {
@override
Widget build(BuildContext context) {
final painter = Painter();
return Stack(
children: [
SizedBox(
width: 0,
height: 0,
child: DropdownButtonFormField<String>(
onChanged: (value) {}, items: const []),
),
GestureDetector(
onTap: () {
setState(() {
painter.addY(10);
});
},
child: CustomPaint(
painter: Painter(),
child: Container(),
)),
],
);
}
}
class Painter extends CustomPainter {
double y = 10;
addY(val) {
y += val;
}
@override
void paint(Canvas canvas, Size size) {
debugPrint('paint');
canvas.drawCircle(Offset(size.width / 2, y++), 100, Paint());
}
@override
bool shouldRepaint(Painter oldDelegate) {
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With