flutter - 自定义小部件引发事件在颤动中不起作用
问题描述
我需要一个自定义小部件来在我的页面上绘制垂直和水平线,我可以在运行时调整小部件的大小。我将 DrawLine 的 GestureDetector 与油漆和画布结合起来,所以我有一个名为Line的类,我可以在这个类上绘制我的线条
所以我在颤振中创建了一个自定义小部件,用于在运行时绘制具有调整大小属性的垂直线
我在颤振上写了这段代码
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;
}
}
我在我的页面上画了 3 行但只有最新的行可以调整大小有
什么问题?
解决方案
每一行都画在整个屏幕上,第三行覆盖第一行和第二行,第一行和第二行都不能接收到 GestureDetector 的事件。相反,您可以使用 LayoutBuidler 以相对位置而不是全局位置绘制线条。
推荐阅读
- node.js - 具有角度通用的 WebSocket
- r - 将手动 p 值添加到 ggplot2 中的分组条形图
- php - 只有 PHP 有可能吗?PHP 表单
- javascript - 如何比较对象值
- javascript - 在文档中调用 Node.js <%%> 标记中的本地函数
- c# - 如果使用了 [AllowAnonymous],请在 JwtBearerEvents 中了解
- c - 井字游戏中的 MiniMax 算法
- linux - 如何在 Linux 中使用 getopt?
- javascript - React Native Jest SyntaxError: Duplicate __self prop found
- bash - bash:不要从脚本中提示 select case 语句 - 可能吗?