Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 在颤振中将阵列绘制到可拖动的位置_Flutter - Fatal编程技术网

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);
                  },
                )
            ),
          ],
        )
    );
  }

}