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

Flutter中用GestureDetector配合CustomPaint点击绘制中心线不生效问题

问题原因

  • 你在onTapDown回调中创建的CustomPaint实例没有被加入到Widget渲染树中,仅在回调函数的局部作用域生效,不会被系统渲染到屏幕上
  • ExampleLine的shouldRepaint方法返回了false,就算组件触发更新也不会重新执行绘制逻辑
  • 你没有给CustomPaint指定绘制尺寸,默认尺寸为0*0,就算组件正确挂载也没有绘制空间,无法显示内容

修正方案

1. 新增状态变量控制线条显隐

在你的State类中新增状态变量:

bool _shouldShowLine = false;

2. 修改build层代码

将线条绘制组件放到渲染树中,用状态变量控制显隐:

@override
Widget build(BuildContext context) {
  Size size = MediaQuery.of(context).size;
  return Scaffold(
    body: Stack(children: [
      Positioned(
        left: size.width / 2,
        top: size.height / 2,
        child: CustomPaint(
          painter: Over(),
        ),
      ),
      // 把线条绘制组件放到渲染树中
      if (_shouldShowLine) 
        Positioned.fill(
          child: CustomPaint(
            painter: ExampleLine(xaxis: size.width, yaxis: size.height),
          ),
        ),
      Positioned.fill(
        child: GestureDetector(
          onTapDown: (e) {
            print("tapdown");
            setState(() {
              _shouldShowLine = true;
            });
          },
        ),
      ),
    ]),
  );
}

3. 修改CustomPainter逻辑

修改shouldRepaint返回值允许重绘:

class ExampleLine extends CustomPainter {
  double xaxis, yaxis;
  ExampleLine({required this.xaxis, required this.yaxis});
  @override
  void paint(Canvas canvas, Size size) {
    Paint line = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    Path pline = Path();
    pline.moveTo(xaxis / 2, yaxis / 2);
    pline.lineTo(0, 0);
    canvas.drawPath(pline, line);
  }

  @override
  bool shouldRepaint(covariant ExampleLine oldDelegate) {
    // 当绘制参数变化时触发重绘
    return xaxis != oldDelegate.xaxis || yaxis != oldDelegate.yaxis;
  }
}

内容的提问来源于stack exchange,提问作者friday

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:15:08