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

Flutter中使用CustomPaint延迟添加线条的问题求助

解决CustomPaint延迟绘制图形的问题

你原来的代码错误原因很明确:paint方法执行完毕后,传入的Canvas对象会被Flutter框架回收释放。在Timer的回调里再调用这个已经被销毁的Canvas,自然会抛出"Object has been disposed"异常。

正确的实现思路是通过状态管理触发重绘,而不是直接在paint里操作过期的Canvas。具体步骤如下:

  • 使用StatefulWidget维护一个状态变量,标记是否需要绘制那条延迟的短线
  • 在组件初始化时设置延迟任务,到点后更新状态并触发重绘
  • 在CustomPainter的paint方法中,根据状态变量决定是否绘制额外的线

完整代码示例:

import 'dart:async';
import 'package:flutter/material.dart';

class DelayedPaintDemo extends StatefulWidget {
  const DelayedPaintDemo({super.key});

  @override
  State<DelayedPaintDemo> createState() => _DelayedPaintDemoState();
}

class _DelayedPaintDemoState extends State<DelayedPaintDemo> {
  bool _showExtraLine = false;

  @override
  void initState() {
    super.initState();
    // 延迟1秒后更新状态,触发重绘
    Timer(const Duration(seconds: 1), () {
      if (mounted) { // 先判断组件是否还挂载,避免内存泄漏
        setState(() {
          _showExtraLine = true;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomPaint(
          size: const Size(300, 350),
          painter: _MyPainter(showExtraLine: _showExtraLine),
        ),
      ),
    );
  }
}

class _MyPainter extends CustomPainter {
  final bool showExtraLine;

  _MyPainter({required this.showExtraLine});

  @override
  void paint(Canvas canvas, Size size) {
    const p1 = Offset(50, 50);
    const p2 = Offset(50, 300);
    const p3 = Offset(50, 50);
    const p4 = Offset(250, 50);
    const p5 = Offset(250, 50);
    const p6 = Offset(250, 150);
    const p7 = Offset(250, 150);
    const p8 = Offset(250, 300);

    final paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 4
      ..strokeCap = StrokeCap.round;

    // 绘制初始图形
    canvas.drawLine(p1, p2, paint);
    canvas.drawLine(p3, p4, paint);
    canvas.drawLine(p5, p6, paint);

    // 根据状态决定是否绘制延迟的线
    if (showExtraLine) {
      canvas.drawLine(p7, p8, paint);
    }
  }

  @override
  bool shouldRepaint(covariant _MyPainter oldDelegate) {
    // 当showExtraLine状态变化时,触发重绘
    return oldDelegate.showExtraLine != showExtraLine;
  }
}

代码说明:

  • _showExtraLine变量控制是否显示延迟的短线,初始为false
  • initState里的Timer延迟1秒后,通过setState更新状态,Flutter会自动调用CustomPaint的paint方法重绘
  • shouldRepaint方法返回true的条件是状态变量变化,确保只有状态改变时才重绘,优化性能
  • 添加mounted判断是为了避免组件已经被销毁时调用setState导致的异常

内容的提问来源于stack exchange,提问作者מאי כהן

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:55:17