首页 > 解决方案 > 如何在 Flutter 中通过拖放将元素移动到父容器内的任何位置?

问题描述

我在 Flutter 中使用 Draggable 小部件,我想将我的元素移动到父小部件内的任何位置。

我尝试了 dragtarget 小部件,但无法将其设置为我的父小部件。我还尝试了onDraggableCanceledDraggable 小部件的方法来获取偏移量,并将其应用于元素的新偏移量,但它给了我来自设备的偏移量,而不是来自父容器的偏移量。

那么,这样做的正确方法是什么?

标签: flutterdrag-and-drop

解决方案


刚刚在 Flutter Web 中的拖放画布上遇到了同样的问题。我最终通过为每个可拖动的小部件插入一个 GlobalKey 并通过考虑包含渲染框的大小来调整放置偏移量来解决这个问题(在等待渲染完成后,通过 addPostFrameCallback())。为了便于精确放置,我使用了 Stack()/Positioned() 并将 Draggable() 放置在其中:

import 'package:flutter/material.dart';

class PositionedDraggableIcon extends StatefulWidget {
  final double top;
  final double left;

  PositionedDraggableIcon({Key key, this.top, this.left}) : super(key: key);

  @override
  _PositionedDraggableIconState createState() => _PositionedDraggableIconState();
}

class _PositionedDraggableIconState extends State<PositionedDraggableIcon> {
  GlobalKey _key = GlobalKey();
  double top, left;
  double xOff, yOff;

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
    top = widget.top;
    left = widget.left;
    super.initState();
  }

  void _getRenderOffsets() {
    final RenderBox renderBoxWidget = _key.currentContext.findRenderObject();
    final offset = renderBoxWidget.localToGlobal(Offset.zero);

    yOff = offset.dy - this.top;
    xOff = offset.dx - this.left;
  }

  void _afterLayout(_) {
    _getRenderOffsets();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      key: _key,
      top: top,
      left: left,
      child: Draggable(
        child: Icon(Icons.input),
        feedback: Icon(Icons.input),
        childWhenDragging: Container(),
        onDragEnd: (drag) {
          setState(() {
            top = drag.offset.dy - yOff;
            left = drag.offset.dx - xOff;
          });
        },
      ),
    );
  }
}

可能可以使用小部件上下文本身来执行此操作并避免使用 GlobalKey,但这对我来说已经足够好了。


推荐阅读