我同意您必须将CustomPainter放入具有大小的窗口小部件中。它可能是一个SizedBox,所以我在这里使用了它。幸运的是,您不需要进行手动命中测试,因为CustomPainter可以通过一些重构即可为您处理。首先要注意的是,不需要在每个paint()上重建路径-
可以在构造函数中构建路径。这使CustomPainter的hitTest可以简单地询问水龙头在路径内还是路径外。
class _SegmentPainter extends CustomPainter { static const offset = -pi / 2; double start; double end; double innerRadius; double outerRadius; Color color; Path path; _SegmentPainter( this.start, this.end, this.innerRadius, this.outerRadius, this.color) { path = new Path() ..arcTo( Rect.fromCircle(center: new Offset(0.0, 0.0), radius: outerRadius), offset + start, end - start, true) ..relativeLineTo(-cos(offset + end) * (outerRadius - innerRadius), -sin(offset + end) * (outerRadius - innerRadius)) ..arcTo( Rect.fromCircle(center: new Offset(0.0, 0.0), radius: innerRadius), offset + end, start - end, false) ..close(); } @override bool shouldRepaint(_SegmentPainter oldDelegate) { return oldDelegate.start != start || oldDelegate.end != end || oldDelegate.innerRadius != innerRadius || oldDelegate.outerRadius != outerRadius || oldDelegate.color != color; } @override bool shouldRebuildSemantics(_SegmentPainter oldDelegate) => true; @override void paint(Canvas canvas, Size size) { canvas.drawPath( path, new Paint() ..color = color ..style = PaintingStyle.fill); } @override bool hitTest(Offset position) { return path.contains(position); }}class SegmentWidget extends StatelessWidget { @override Widget build(BuildContext context) { return new GestureDetector( onTap: () => print('tap'), child: new SizedBox( width: 250.0, height: 250.0, child: new CustomPaint( painter: new _SegmentPainter(0.0, 2.8, 150.0, 200.0, Colors.orange), ), ), ); }}我使用了Dart
..(级联)语法来清理路径。(我认为您的
should...测试被否定了。)我添加了一个StatelessWidget,作为
SizedBoxand
的主页
GestureDetector。



