简体   繁体   English

自定义小部件引发事件在颤振中不起作用

[英]Custom widget raise event not working property in flutter

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我将 DrawLine 的 GestureDetector 与油漆和画布结合起来,所以我有一个名为Line的类,我可以在这个类上绘制我的线条

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我在我的页面上画了 3 行,但只有最新的行可以调整大小
whats the problem?有什么问题?

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.每一行都画在整个屏幕上,第三行覆盖了第一行和第二行,第一行和第二行都不能接收GestureDetector的事件。 Instead, you can use LayoutBuidler to draw line with relative position not global postion.相反,您可以使用 LayoutBuidler 绘制具有相对位置而不是全局位置的线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM