Flutter应用paint方法未执行,绘制循环无触发问题求助
Flutter绘图不生效问题修复
问题根源
你的代码中CustomPainter的shouldRepaint方法判断逻辑有误:由于points是List引用类型,调用add或clear时列表的引用并未改变,导致oldDelegate.points != points始终返回false,CustomPainter不会触发重绘。因此即便手势更新时添加了点,paint方法也不会重新执行,自然看不到"Line drawn!"输出。
修复方案
有两种可行的修复方式,选其一即可:
方式一:修改shouldRepaint逻辑,比较列表内容
直接判断两个列表的内容是否不同,而不是比较引用:
class PaintField extends CustomPainter { List<Offset> points; PaintField(this.points); @override void paint(Canvas canvas, Size size) { Paint paint = Paint() ..color = Colors.black ..strokeCap = StrokeCap.round ..strokeWidth = 5.0; print("Points length: ${points.length}"); for (int i = 1; i < points.length; i++) { canvas.drawLine(points[i - 1], points[i], paint); print("Line drawn!"); } } @override bool shouldRepaint(PaintField oldDelegate) { // 先比较长度,长度不同直接需要重绘 if (oldDelegate.points.length != points.length) return true; // 逐个比较元素,有不同则需要重绘 for (int i = 0; i < points.length; i++) { if (oldDelegate.points[i] != points[i]) return true; } return false; } }
方式二:更新points时创建新列表实例
每次更新points时生成新的列表,确保引用发生变化,让原有的shouldRepaint逻辑生效:
class _MyAppState extends State<MyApp> { List<Offset> points = []; void handlePanUpdate(DragUpdateDetails details) { print("handled Pan Update"); setState(() { // 创建新列表并添加新点 points = List.from(points)..add(details.localPosition); }); } void handlePanEnd(DragEndDetails details) { print("handled Drag End"); setState(() { // 直接赋值新的空列表 points = []; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Container( color: Colors.blueGrey[50], child: GestureDetector( onPanUpdate: handlePanUpdate, onPanEnd: handlePanEnd, child: CustomPaint( painter: PaintField(points), size: Size.infinite, ), ), ), ); } }
效果验证
修复后,滑动手势时points更新会触发setState,CustomPainter会正确重绘,控制台会输出"Points length: X"和"Line drawn!",同时画布上会显示绘制的线条。
内容的提问来源于stack exchange,提问作者HelloToxicity
相关产品推荐
相关产品推荐

