首页 > 解决方案 > 如何为某个小部件 Flutter 指定拖动目标(单个 Draggable 被放入 3 个拖动目标而不是 1 个)

问题描述

这是我面临的问题:

我从一个表情符号列表开始,我想将其放入这 3 个放置目标中

(我希望能够选择进入每个放置目标的每个表情符号) 在此处输入图像描述

当我拖动其中一个表情符号时(只有一个,在这种情况下是第一个,它会自动落入所有拖动目标,而不仅仅是第一个)。

这会导致相同的表情符号无意中填充所有拖动目标,这是意想不到的行为:

在此处输入图像描述

我的问题是,如何更改我的代码,以确保当我将表情符号拖动到第一个、第二个或第三个拖动目标时,只有相应的拖动目标被填充而不是全部填充?非常感谢,我非常感谢您的帮助!

拖动框代码:

class DragBox extends StatefulWidget {
  DragBox({this.animatedAsset, this.width});
  final LottieBuilder animatedAsset;
  final double width;
  @override
  _DragBoxState createState() => _DragBoxState();
}

class _DragBoxState extends State<DragBox> {
  @override
  Widget build(BuildContext context) {
    return Draggable(
      feedback: Container(
        width: 50,
        height: 50,
        child: widget.animatedAsset,
      ),
      child: Container(
        child: widget.animatedAsset,
        width: widget.width,
        height: 50,
      ),
      childWhenDragging: Container(),
      data: widget.animatedAsset,
    );
  }
}

表情符号选择器代码:

class AnimatedEmojiPicker extends StatefulWidget {
  @override
  _AnimatedEmojiPickerState createState() => _AnimatedEmojiPickerState();
}

class _AnimatedEmojiPickerState extends State<AnimatedEmojiPicker> {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 10.0, right: 10.0),
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: 60,
        decoration:
            BoxDecoration(color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
        child: ListView(
          scrollDirection: Axis.horizontal,
          children: <Widget>[
            Container(
              width: 15,
            ),
            DragBox(
              animatedAsset: Lottie.asset('Assets/blushing.json'),
            ),
            Container(
              width: 15,
            ),
            DragBox(
              animatedAsset: Lottie.asset('Assets/cooldude.json'),
            ),
            Container(
              width: 15,
            ),
            DragBox(
              animatedAsset: Lottie.asset('Assets/zipmouth.json'),
            ),
            //More drag boxes like this one
          ],
        ),
      ),
    );
  }
}

我的拖动目标:

                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  DragTarget(
                    onAccept: (LottieBuilder animation) {
                      setState(() {
                        widget.caughtAnimation = animation;
                      });
                    },
                    builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                      return Center(
                        child: Container(
                          height: 60,
                          width: 60,
                          decoration: BoxDecoration(
                              color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
                          child: widget.caughtAnimation,
                        ),
                      );
                    },
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: DragTarget(
                      onAccept: (LottieBuilder animation) {
                        setState(() {
                          widget.caughtAnimation = animation;
                        });
                      },
                      builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                        return Center(
                          child: Container(
                            height: 60,
                            width: 60,
                            decoration: BoxDecoration(
                                color: Colors.grey.shade400.withOpacity(0.5),
                                borderRadius: BorderRadius.circular(20.0)),
                            child: widget.caughtAnimation,
                          ),
                        );
                      },
                    ),
                  ),
                  DragTarget(
                    onAccept: (LottieBuilder animation) {
                      setState(() {
                        widget.caughtAnimation = animation;
                      });
                    },
                    builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                      return Center(
                        child: Container(
                          height: 60,
                          width: 60,
                          decoration: BoxDecoration(
                              color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
                          child: widget.caughtAnimation,
                        ),
                      );
                    },
                  ),
                ],
              ),

再次感谢您的帮助!

标签: androidiosflutterdartdrag-and-drop

解决方案


发生这种情况是因为您在每个回调上DragTarget都构建了与widget.caughtAnimation您在任何onAccept回调上设置的相同的内容。

考虑以您可以单独修改每个 DragTarget 的方式构建小部件状态模型,这可以通过列表/数组或地图来完成。

List<LottieBuilder> caughtAnimations;

然后

                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  DragTarget(
                    onAccept: (LottieBuilder animation) {
                      setState(() {
                        caughtAnimations[0] = animation;
                      });
                    },
                    builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                      return Center(
                        child: Container(
                          height: 60,
                          width: 60,
                          decoration: BoxDecoration(
                              color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
                          child: caughtAnimations[0],
                        ),
                      );
                    },
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: DragTarget(
                      onAccept: (LottieBuilder animation) {
                        setState(() {
                          caughtAnimations[1] = animation;
                        });
                      },
                      builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                        return Center(
                          child: Container(
                            height: 60,
                            width: 60,
                            decoration: BoxDecoration(
                                color: Colors.grey.shade400.withOpacity(0.5),
                                borderRadius: BorderRadius.circular(20.0)),
                            child: caughtAnimations[1],
                          ),
                        );
                      },
                    ),
                  ),
                  DragTarget(
                    onAccept: (LottieBuilder animation) {
                      setState(() {
                        caughtAnimations[2] = animation;
                      });
                    },
                    builder: (BuildContext context, List<dynamic> candidateData, List<dynamic> rejectedData) {
                      return Center(
                        child: Container(
                          height: 60,
                          width: 60,
                          decoration: BoxDecoration(
                              color: Colors.grey.shade400.withOpacity(0.5), borderRadius: BorderRadius.circular(20.0)),
                          child: caughtAnimations[2],
                        ),
                      );
                    },
                  ),
                ],
              ),

推荐阅读