Reputation: 321
I am trying to create some custom widgets using CustomPaint and GestureDetector. However, I am unable to properly interact with the drawn shapes using the GestureDetector. I can detect onTap for only one shape if the container is screen width and height, or none at all.
Please note that I have tried all HitTestBehavior
types.
Here is the code whilst it's not detecting anything onTap:
class CanvasObject {
Color color = Colors.green[800];
double strokeWidth = 10.0;
PaintingStyle style = PaintingStyle.stroke;
}
class CanvasNodeObject extends CanvasObject {
double x;
double y;
double radius = 20;
PaintingStyle style = PaintingStyle.fill;
CanvasNodeObject({@required this.x, @required this.y});
}
class CanvasNodePainter extends CustomPainter {
CanvasNodeObject node;
CanvasNodePainter({this.node});
@override
void paint(Canvas canvas, Size size) {
Path path;
Paint nodePaint = Paint()
..color = node.color
..style = node.style;
path = Path();
path.moveTo(0, 0);
path.addOval(
Rect.fromCircle(center: Offset(0, 0), radius: node.radius));
canvas.drawPath(path, nodePaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class TestLineDrawing extends StatefulWidget {
CanvasNodeObject startNode;
CanvasNodeObject endNode;
CanvasLineObject line;
TestLineDrawing({List<double> x, List<double> y})
: assert(x.length == 2),
assert(y.length == 2) {
startNode = CanvasNodeObject(x: x[0], y: y[0]);
endNode = CanvasNodeObject(x: x[1], y: y[1]);
line = CanvasLineObject(x: x, y: y);
}
@override
_TestLineDrawingState createState() => _TestLineDrawingState();
}
class _TestLineDrawingState extends State<TestLineDrawing> {
List<Widget> line() {
return [
Positioned(
top: widget.endNode.x,
left: widget.endNode.y,
child:
GestureDetector(
behavior: HitTestBehavior.opaque,
child:
Container(
height: widget.endNode.radius,
width: widget.endNode.radius,
child: CustomPaint(painter: CanvasNodePainter(node: widget.endNode))),
onTap: () {
setState(() {
Random random = Random();
widget.endNode.color = Color.fromARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
debugPrint("EndNodeOnPress " + widget.endNode.color.toString());
});
},
)),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: line(),
));
}
Upvotes: 1
Views: 2133
Reputation: 321
I resolved this issue by doing the following:
path
using Path::addPath
hitTest
and using Path::contains
@override
bool hitTest(Offset position) {
bool hit = path.contains(position);
return hit;
}
Upvotes: 1