Flutter 在颤振中将阵列绘制到可拖动的位置
我在堆栈中有一个可拖动容器数组,我想创建一个指向另一个的箭头。Flutter 在颤振中将阵列绘制到可拖动的位置,flutter,Flutter,我在堆栈中有一个可拖动容器数组,我想创建一个指向另一个的箭头。 我找到的最好的方法是在堆栈的背景上放置一个CustomPainter,并在每次视图位置发生变化时绘制数组(现在它只是一条线,以查看是否一切都顺利运行)。 当我的容器不移动时(左边的线): 现在我的问题是,当拖动我的对象时,容器的位置和行之间会出现不同步(滞后?)。 我如何解决这个问题 有没有更好的方法来制作这些箭 这是我的代码: ExampleContainer(构建包含所有ExampleView的堆栈) 示例视图(可拖
我找到的最好的方法是在堆栈的背景上放置一个CustomPainter,并在每次视图位置发生变化时绘制数组(现在它只是一条线,以查看是否一切都顺利运行)。
当我的容器不移动时(左边的线):
现在我的问题是,当拖动我的对象时,容器的位置和行之间会出现不同步(滞后?)。
- 我如何解决这个问题
- 有没有更好的方法来制作这些箭
这是我的代码:
ExampleContainer(构建包含所有ExampleView的堆栈)
示例视图(可拖动视图容器)。我发现获取容器当前位置的最佳方法是使用侦听器,但我觉得奇怪的是,我没有其他方法
class ExampleView extends StatefulWidget {
ExampleView({Key key, this.parent, this.id, this.width, this.height, this.x = 0, this.y = 0}): super(key: key);
final double width;
final double height;
final double x;
final double y;
final String id;
final ExampleContainerState parent;
@override
_ExampleView createState() => _ExampleView();
Offset getArrowPosition() {
return Offset(x, y + (height / 2));
}
}
class _ExampleView extends State<ExampleView> {
final GlobalKey _feedbackKey = GlobalKey();
void endMove(Offset offset) {
widget.parent.positionDidMove(widget.id, offset);
}
void move(Offset offset) {
Offset left = Offset(offset.dx, offset.dy + (widget.height / 2));
widget.parent.positionMoving(widget.id, left);
}
Container getContainer() {
return Container(
child: Center(child: Text('Container'),),
width: widget.width,
height: widget.height,
margin: EdgeInsets.fromLTRB(0, 0, 0, 5),
decoration: BoxDecoration(
border: Border.all(width: 1),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
);
}
@override
Widget build(BuildContext context) {
return Positioned(
top: widget.y,
left: widget.x,
child: Column(
children: <Widget>[
Listener(
onPointerMove: (PointerMoveEvent event) {
if (this._feedbackKey.currentContext == null)
return;
RenderBox tmp = this._feedbackKey.currentContext.findRenderObject();
this.move(tmp.localToGlobal(Offset.zero));
},
child: Draggable(
child: this.getContainer(),
feedback: Container(child: this.getContainer(), key: this._feedbackKey),
childWhenDragging: Container(),
onDraggableCanceled: (Velocity velocity, Offset offset){
this.endMove(offset);
},
)
),
],
)
);
}
}
class ExampleView扩展StatefulWidget{
ExampleView({Key,this.parent,this.id,this.width,this.height,this.x=0,this.y=0}):super(Key:Key);
最终双倍宽度;
最终双倍高度;
最后的双x;
最后双y;
最终字符串id;
最后一个示例ContainerState父级;
@凌驾
_ExampleView createState()=>\u ExampleView();
偏移量getArrowPosition(){
返回偏移量(x,y+(高度/2));
}
}
类_示例视图扩展状态{
最终GlobalKey _feedbackKey=GlobalKey();
void endMove(偏移){
widget.parent.positionDidMove(widget.id,偏移量);
}
无效移动(偏移){
左偏移量=偏移量(Offset.dx,Offset.dy+(widget.height/2));
widget.parent.positionMoving(widget.id,左侧);
}
容器getContainer(){
返回容器(
子对象:中心(子对象:文本('Container'),),
宽度:widget.width,
高度:widget.height,
边距:从LTRB(0,0,0,5)开始的边距集,
装饰:盒子装饰(
边框:边框。全部(宽度:1),
borderRadius:borderRadius.all(半径.圆形(5.0)),
),
);
}
@凌驾
小部件构建(构建上下文){
返回定位(
顶部:widget.y,
左:widget.x,
子:列(
儿童:[
听众(
onPointerMove:(PointerMoveEvent事件){
if(this.\u feedbackKey.currentContext==null)
返回;
RenderBox tmp=this._feedbackKey.currentContext.findenderobject();
this.move(tmp.localToGlobal(Offset.zero));
},
孩子:拖拉(
子级:this.getContainer(),
反馈:容器(子项:this.getContainer(),键:this.\u feedbackKey),
ChildWhenDraging:容器(),
ONDRAGABLECED:(速度、偏移量){
此.endMove(偏移量);
},
)
),
],
)
);
}
}
感谢所有花时间阅读我的问题的人。这是我在Flatter中的第一个测试,我愿意接受任何意见来改进我的代码。
编辑:我添加了一个问题的视频如果可能,您能否与多个容器和所有箭头共享完整的屏幕截图。@CrazyLazyCat我刚刚添加了一个问题视频,您可以在其中看到多个容器。正如我所说的,现在只是在每个容器的左边画一条线,看看是否一切都顺利进行。
class ArrowPainter extends CustomPainter {
ArrowPainter({this.viewsInfo});
final Map viewsInfo;
@override
void paint(Canvas canvas, Size size) {
viewsInfo.forEach((k, v) {
final p1 = Offset(v['leftArrow'].dx, v['leftArrow'].dy);
final p2 = Offset(v['leftArrow'].dx - 20, v['leftArrow'].dy);
final paint = Paint()
..color = Colors.black
..strokeWidth = 4;
canvas.drawLine(p1, p2, paint);
});
}
@override
bool shouldRepaint(ArrowPainter old) {
return true;
}
}
class ExampleView extends StatefulWidget {
ExampleView({Key key, this.parent, this.id, this.width, this.height, this.x = 0, this.y = 0}): super(key: key);
final double width;
final double height;
final double x;
final double y;
final String id;
final ExampleContainerState parent;
@override
_ExampleView createState() => _ExampleView();
Offset getArrowPosition() {
return Offset(x, y + (height / 2));
}
}
class _ExampleView extends State<ExampleView> {
final GlobalKey _feedbackKey = GlobalKey();
void endMove(Offset offset) {
widget.parent.positionDidMove(widget.id, offset);
}
void move(Offset offset) {
Offset left = Offset(offset.dx, offset.dy + (widget.height / 2));
widget.parent.positionMoving(widget.id, left);
}
Container getContainer() {
return Container(
child: Center(child: Text('Container'),),
width: widget.width,
height: widget.height,
margin: EdgeInsets.fromLTRB(0, 0, 0, 5),
decoration: BoxDecoration(
border: Border.all(width: 1),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
);
}
@override
Widget build(BuildContext context) {
return Positioned(
top: widget.y,
left: widget.x,
child: Column(
children: <Widget>[
Listener(
onPointerMove: (PointerMoveEvent event) {
if (this._feedbackKey.currentContext == null)
return;
RenderBox tmp = this._feedbackKey.currentContext.findRenderObject();
this.move(tmp.localToGlobal(Offset.zero));
},
child: Draggable(
child: this.getContainer(),
feedback: Container(child: this.getContainer(), key: this._feedbackKey),
childWhenDragging: Container(),
onDraggableCanceled: (Velocity velocity, Offset offset){
this.endMove(offset);
},
)
),
],
)
);
}
}