You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:48:32