Flutter touchable库CanvasTouchDetector的tap事件无法触发问题
问题排查与修复方案
- 确认
LevelPainter的paint方法参数类型正确
普通CustomPainter的paint方法默认接收的是Canvas类型参数,你需要将其修改为TouchyCanvas,且必须在paint方法内调用你写的_drawSwitch方法,确保你调用drawRRect时用的是touchable库注入的TouchyCanvas实例,而不是系统原生Canvas:
- 确认
// 错误写法 class LevelPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { // 这里的canvas是原生Canvas,调用drawRRect不会绑定事件 } } // 正确写法 class LevelPainter extends CustomPainter { @override void paint(TouchyCanvas canvas, Size size) { // 用TouchyCanvas类型接收参数,再调用_drawSwitch _drawSwitch(canvas, paint, switchable); } }
- 确保
CustomPaint的尺寸覆盖你的绘制区域
你当前的CustomPaint没有指定尺寸,会默认适配child的大小,如果你的Center套的Container没有设置宽高,CustomPaint的可点击区域会远小于实际绘制区域,触摸事件无法被捕获。修改你的布局代码,给CustomPaint设置全屏/匹配父容器的尺寸:
- 确保
return Scaffold( appBar: AppBar(title: Text('Lights'), centerTitle: true), body: CanvasTouchDetector( builder: (context) => SizedBox.expand( // 新增Expand让CustomPaint占满父容器 child: CustomPaint( painter: LevelPainter( switches: this._switches, connections: this._connections, context: context ), ), ) ) );
- 确认
shouldRepaint返回值正确
如果你的LevelPainter的shouldRepaint方法返回了false,touchable库无法完成手势回调的绑定,需要确保页面初始化或者状态更新时,shouldRepaint返回true触发重绘绑定事件:
- 确认
@override bool shouldRepaint(LevelPainter oldDelegate) { return true; // 或者根据你的状态变化判断返回true }
- 检查是否有上层组件拦截触摸事件
确认CanvasTouchDetector和CustomPaint上层没有其他GestureDetector、Listener或者透明组件吸收了触摸事件,导致事件无法传递到touchable库的手势处理器。
- 检查是否有上层组件拦截触摸事件
- 确认
_getRectForSwitchable返回的坐标正确
检查你生成的RRect坐标是否在CustomPaint的尺寸范围内,如果坐标超出了CustomPaint的边界,也无法触发对应的点击回调。
- 确认
内容的提问来源于stack exchange,提问作者nuttykeeper
相关产品推荐
相关产品推荐

