Home > Software engineering >  Gesture detector in stack causing the other one to not work
Gesture detector in stack causing the other one to not work

Time:09-07

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! enter image description here

   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,
                                      ),
                                    ),
                                  ),
                                ),
                              ]),
                            ))
  • Related