如何解决自定义窗口小部件引发事件在flutter中不起作用
我需要一个自定义小部件来在页面上绘制垂直和水平线,我可以在运行时调整小部件的大小。我将DrawLine的GestureDetector与油漆和画布结合在一起,所以我有一个名为 Line 的类,并且可以在此类上绘制线条
所以我在Flutter中创建了一个自定义小部件,用于在运行时使用resize属性绘制垂直线
我在扑扑的时候写这段代码
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,],);
}
}
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,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;
}
}
我在页面上画了3行,但只有最新的行可以调整大小
有什么问题吗?
解决方法
每条线在整个屏幕上绘制,第三条线覆盖第一条和第二条线,第一条线和第二条线都不能接收GestureDetector事件。相反,您可以使用LayoutBuidler绘制相对位置而非全局位置的线。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。