I have 2 gesture dectector( one for the red circle and the other for the blue circle) which is use to drag them around the XY plane. however only one of them is working(blue one). As the blue gesture detector area is overlapping the red one. Is there any way i can solve this? i have tried methods like setting the gesture detector behaviour but its still not working. Thanks in advance!
import 'package:flutter/material.dart';
import'dart:math';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool isDown = false;
var XSourceP = 5.0;
var YSourceP = 5.0;
var XFieldP = 55.0;
var YFieldP = 55.0;
double radiuspoint =10.0;
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Builder(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Point Charge'),),
body: Column(
children: [
Text('Hello'),
Center(
child: Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height*0.3,
width: MediaQuery.of(context).size.width,
color: Colors.grey,
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: LayoutBuilder(
builder: (_,constraints)=> Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.white,
child: Stack(
children: [
// plotting X Y axis
Container(
width: constraints.widthConstraints().maxWidth,
height:constraints.heightConstraints().maxHeight,
child:CustomPaint(painter: PlotPainter())
),
// for source point( Red circle)
GestureDetector(
onPanUpdate: (details) {
final tapPos = details.localPosition;
if (tapPos.dx>0 && tapPos.dx<constraints.widthConstraints().maxWidth-radiuspoint)
{
setState(() {
XSourceP = tapPos.dx radiuspoint ;
});
}
if (tapPos.dy>radiuspoint && tapPos.dy<constraints.heightConstraints().maxHeight)
{
setState(() {
YSourceP = tapPos.dy - radiuspoint ;
});
}
},
child: SizedBox(
width: constraints.widthConstraints().maxWidth,
height:constraints.heightConstraints().maxHeight,
child: CustomPaint(painter: PointsPainter(XSourceP, YSourceP, radiuspoint),
)),
),
//field point(BLUE circle)
GestureDetector(
behavior: HitTestBehavior.opaque,
onPanUpdate: (details) {
final tapPosF = details.localPosition;
if (tapPosF.dx>0 && tapPosF.dx<constraints.widthConstraints().maxWidth-radiuspoint)
{
setState(() {
XFieldP = tapPosF.dx radiuspoint ;
});
}
if (tapPosF.dy>radiuspoint && tapPosF.dy<constraints.heightConstraints().maxHeight)
{
setState(() {
YFieldP = tapPosF.dy - radiuspoint ;
});
}
},
child: SizedBox(
width: constraints.widthConstraints().maxWidth,
height:constraints.heightConstraints().maxHeight,
child: CustomPaint(painter: FieldPointsPainter(XFieldP , YFieldP, radiuspoint),
)),
),
]),
)
),
),
),
],
),
);
}
)
);
}
}
//drawing blue circle
class FieldPointsPainter extends CustomPainter {
FieldPointsPainter(this.XFieldP , this.YFieldP, this.radiuspoint);
double XFieldP,YFieldP, radiuspoint;
@override
void paint(Canvas canvas, Size size) {
// TODO: implement points
final midY = size.height/2;
final midX = size.width/2;
final CirclepaintF = Paint()..style = PaintingStyle.fill
..color = Colors.blue;
canvas.drawCircle(Offset(XFieldP, YFieldP), radiuspoint, CirclepaintF);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
//drawing red circle
class PointsPainter extends CustomPainter {
PointsPainter(this.XSourceP , this.YSourceP, this.radiuspoint);
double XSourceP, YSourceP, radiuspoint;
@override
void paint(Canvas canvas, Size size) {
// TODO: implement points
final midY = size.height/2;
final midX = size.width/2;
final CirclepaintS = Paint()..style = PaintingStyle.fill
..color = Colors.red;
canvas.drawCircle(Offset(XSourceP, YSourceP), radiuspoint, CirclepaintS);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
// drawing the x y axis
class PlotPainter extends CustomPainter {
@override void paint(Canvas canvas, Size size){
final midY = size.height/2;
final midX = size.width/2;
final paint = Paint()..style = PaintingStyle.fill
..color = Colors.black
..strokeWidth=1.0;
final textPainterx = TextPainter(
text: const TextSpan(
text: 'x',
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
),
textDirection: TextDirection.ltr,
textAlign: TextAlign.center
);
final textPaintery = TextPainter(
text: const TextSpan(
text: 'y',
style: TextStyle(
color: Colors.black,
fontSize: 13,
),
),
textDirection: TextDirection.ltr,
textAlign: TextAlign.center
);
// X axis
canvas.drawLine(Offset(0,midY), Offset(size.width,midY), paint);
//y Axis
canvas.drawLine(Offset(midX,0), Offset(midX,size.height), paint);
//arrow head of the X-Y Axis
canvas.drawLine(Offset(size.width,midY),Offset(size.width -5,midY -3) , paint);
canvas.drawLine(Offset(size.width,midY),Offset(size.width -5,midY 3) , paint);
canvas.drawLine(Offset(midX,0), Offset(midX-3,5), paint);
canvas.drawLine(Offset(midX,0), Offset(midX 3,5), paint);
textPainterx.layout();
textPaintery.layout();
// Draw the text X at the X axis
textPainterx.paint(canvas, Offset(size.width-7,midY 1));
// Draw the text y at the Y axis
textPaintery.paint(canvas, Offset(midX 5,0));
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
CodePudding user response:
You are setting a invisible container and set gesture detected to it and every time gesture detect any you repaint that dot shape, but you invisible container still at same place it was before, and because you are using stack widget you invisible blue container is allways on your invisible red container,so you should change the position of these container not repaint that dot. you can try this code, but it needs to be edited:
LayoutBuilder(
builder: (_, constraints) => Container(
width: constraints.widthConstraints().maxWidth,
height: constraints.heightConstraints().maxHeight,
color: Colors.white,
child: Stack(children: [
// plotting X Y axis
Container(
width:
constraints.widthConstraints().maxWidth,
height: constraints
.heightConstraints()
.maxHeight,
child: CustomPaint(painter: PlotPainter())),
// for source point( Red circle)
Positioned(
top: YSourceP,
left: XSourceP,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onPanUpdate: (details) {
final tapPos = details.localPosition;
if (tapPos.dx > 0 &&
tapPos.dx <
constraints
.widthConstraints()
.maxWidth -
radiuspoint) {
setState(() {
XSourceP = tapPos.dx radiuspoint;
});
}
if (tapPos.dy > radiuspoint &&
tapPos.dy <
constraints
.heightConstraints()
.maxHeight) {
setState(() {
YSourceP = tapPos.dy - radiuspoint;
});
}
},
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
),
//field point(BLUE circle)
Positioned(
top: YFieldP,
left: XFieldP,
child: GestureDetector(
onPanUpdate: (details) {
final tapPosF = details.localPosition;
if (tapPosF.dx > 0 &&
tapPosF.dx <
constraints
.widthConstraints()
.maxWidth -
radiuspoint) {
setState(() {
XFieldP = tapPosF.dx radiuspoint;
});
}
if (tapPosF.dy > radiuspoint &&
tapPosF.dy <
constraints
.heightConstraints()
.maxHeight) {
setState(() {
YFieldP = tapPosF.dy - radiuspoint;
});
}
},
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.blue,
),
),
),
),
]),
))