首页 > 解决方案 > 可拖动的孩子不会落在拖动目标,而是回到它的位置

问题描述

我正在尝试将draggable孩子放置/放置到相应的 上dragtarget,但它不会被放置并返回到原来的位置。

在此处输入图像描述

正如你从图片中看到的,我想把匹配的字母red container放在上面green container,但是一旦我释放指针,它red container就会返回并再次green container显示?。下面是DraggableDragTarget代码片段:

Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: inputList.map((i) {
              print(i);
              return Draggable<String>(
                data: i,
                feedback: Container(
                    margin: EdgeInsets.only(right: 5),
                    alignment: Alignment.center,
                    width: 50,
                    height: 50,
                    decoration: BoxDecoration(
                        color: Colors.red,
                        borderRadius: BorderRadius.circular(20)),
                    child: Text(i.toUpperCase(),
                        style: TextStyle(color: Colors.white, fontSize: 18),
                        textAlign: TextAlign.center)),
                child: Container(
                    margin: EdgeInsets.only(right: 5),
                    alignment: Alignment.center,
                    width: 50,
                    height: 50,
                    decoration: BoxDecoration(
                      color: Colors.blue,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Text(i.toUpperCase(),
                        style: TextStyle(color: Colors.white, fontSize: 18),
                        textAlign: TextAlign.center)),
              );
            }).toList(),
          ),
          Padding(
              padding: EdgeInsets.only(top: 15),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: outputList.map((o) {
                  return DragTarget<String>(
                      builder: (BuildContext context,
                          List<String> candidateData,
                          List<dynamic> rejectedData) {
                        if (candidateData.isEmpty) {
                          return Container(
                              margin: EdgeInsets.only(right: 5),
                              alignment: Alignment.center,
                              width: 50,
                              height: 50,
                              decoration: BoxDecoration(
                                color: Colors.blue,
                                borderRadius: BorderRadius.circular(20),
                              ),
                              child: Text('?',
                                  style: TextStyle(
                                      color: Colors.white, fontSize: 18),
                                  textAlign: TextAlign.center));
                        } else {
                          return Container(
                              margin: EdgeInsets.only(right: 5),
                              alignment: Alignment.center,
                              width: 50,
                              height: 50,
                              decoration: BoxDecoration(
                                color: Colors.green,
                                borderRadius: BorderRadius.circular(20),
                              ),
                              child: Text(o.toUpperCase(),
                                  style: TextStyle(
                                      color: Colors.white, fontSize: 18),
                                  textAlign: TextAlign.center));
                        }
                      },
                      onWillAccept: (data) => data == o,
                      onAccept: (data) {
                        setState(() {
                         // what to set here
                        });
                      },
                      onLeave: (data) {});
                }).toList(),
              )),

不确定我在上面的代码中遗漏了什么。基本上我希望在使用拖放时将所有?容器替换为相应的字母。blue container

有人知道这个的解决方案吗?

标签: flutter

解决方案


文档中:

构建器可以根据被拖动到此拖动目标中的内容来构建不同的小部件。

您需要检查构建器回调中的候选数据(acceptedData)是否不为空,在这种情况下,返回一个包含匹配后者的小部件。

builder: (...) =>
  candidateData.isNotEmpty
    //The returning widget for the matched letter.
    ? Container()
    //The returning widget for the un-matched letter or without dragging anything.
    : Container(),

每次在此 DragTarget 小部件上拖动某些东西时,都会调用构建器 callBack。如果 onWillAccept 回调返回 true,则候选数据 (acceptedData) 不会为空,反之亦然。同样的事情也适用于rejectedData,但方式相反。

所以DragTargetcallBacks执行的顺序是:

  1. builder :最初调用时没有拖动任何东西。
  2. onWillAccept :如果您将某些东西拖过来(按住触摸),则调用。
  3. builder : onWillAccept 之后立即调用,但它的最后两个参数是基于 onWillAccept 结果(仍然保持触摸)。
  4. onAccept 或 onLeave:将调用其中一个,具体取决于您是否将其放下(释放触摸)或将DraggableDragTarget丢弃。
  5. builder:最后一次调用,但此时最后两个参数为空。

推荐阅读