Custom widget raise event not working property in flutter

386 Views Asked by At

i need a custom widget for draw vertical and horizontal line on my page whch i can resize widget on runtime. i combine GestureDetector for DrawLine with paint and canvas, so i have a class with name Line and i can paint my lines on this class

so i create a custom widget in flutter for draw vertical line with resize property on runtime

i write this code on flutter


import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  double height = 300;
  double top = 0;
  double left = 200;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Text Overflow Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Stack(
          children: <Widget>[
            new DrawLineClass(top: 50, left: 100, height: 400),
            new DrawLineClass(top: 100, left: 50, height: 300),
            new DrawLineClass(top: 150, left: 150, height: 300),
          ],
        ),
      ),
    );
  }
}

const double ballDiameter = 20.0;
const double strokeWidth = 10.0;

class DrawLineClass extends StatefulWidget {
  DrawLineClass({Key key, this.top, this.left, this.height}) : super(key: key);

  double height;
  double top;
  double left;

  @override
  _DrawLineClassState createState() => _DrawLineClassState();
}

class _DrawLineClassState extends State<DrawLineClass> {
  @override
  Widget build(BuildContext context) {
    return new Stack(
      children: <Widget>[
        Line(start: {"x": widget.left, "y": widget.top}, end: {"x": widget.left, "y": widget.height}),
        // top middle
        Positioned(
          top: widget.top - ballDiameter / 2,
          left: widget.left - ballDiameter / 2,

          child: new ManipulatingBall(
            onDrag: (dx, dy) {
              setState(() {
                widget.top = widget.top + dy;
              });
            },
          ),
        ),
        // bottom center
        Positioned(
          top: widget.height - ballDiameter / 2,
          left: widget.left - ballDiameter / 2,
          child: new ManipulatingBall(
            onDrag: (dx, dy) {
              var newHeight = widget.height + dy;

              setState(() {
                widget.height = newHeight > 0 ? newHeight : 0;
              });
            },
          ),
        ),
      ],
    );
  }
}

class ManipulatingBall extends StatefulWidget {
  ManipulatingBall({Key key, this.onDrag}) : super(key: key);

  Function onDrag;

  @override
  _ManipulatingBallState createState() => _ManipulatingBallState();
}

class _ManipulatingBallState extends State<ManipulatingBall> {
  double initX;
  double initY;

  _handleDrag(details) {
    setState(() {
      initX = details.globalPosition.dx;
      initY = details.globalPosition.dy;
    });
  }

  _handleUpdate(details) {
    var dx = details.globalPosition.dx - initX;
    var dy = details.globalPosition.dy - initY;
    initX = details.globalPosition.dx;
    initY = details.globalPosition.dy;
    widget.onDrag(dx, dy);
  }

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      behavior: HitTestBehavior.deferToChild,
      onPanStart: _handleDrag,
      onPanUpdate: _handleUpdate,
      child: Container(
        width: ballDiameter,
        height: ballDiameter,
        decoration: BoxDecoration(
          color: Colors.blue.withOpacity(0.5),
          shape: BoxShape.circle,
        ),
      ),
    );
  }
}

class Line extends StatefulWidget {
  final Map<String, double> start;
  final Map<String, double> end;
  Line({this.start, this.end});

  @override
  _LineState createState() => _LineState();
}

class _LineState extends State<Line> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height),
      painter: DrawLine(start: widget.start, end: widget.end),
    );
  }
}

class DrawLine extends CustomPainter {
  Map<String, double> start;
  Map<String, double> end;
  DrawLine({this.start, this.end});

  @override
  void paint(Canvas canvas, Size size) {
    Paint line = new Paint()
      ..color = Colors.red
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.fill
      ..strokeWidth = strokeWidth;
    canvas.drawLine(Offset(start["x"], start["y"]), Offset(end["x"], end["y"]), line);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}

i draw 3 lines on my page but only latest line can be resize
whats the problem?

1

There are 1 best solutions below

0
On

Each line draw on the whole screen, the third line cover the first and second line and both of first line and second line can not receive the events of GestureDetector. Instead, you can use LayoutBuidler to draw line with relative position not global postion.