【问题标题】:How to implement drag and drop with flutter如何用flutter实现拖放
【发布时间】:2019-06-29 11:02:02
【问题描述】:

如何在屏幕上移动我的容器或任何其他小部件并掉落在某些位置?

我发现了颤振小部件DraggableDragTarget。如何使用它们来实现拖放?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    DraggableDragTarget 允许我们在屏幕上拖动一个小部件。 Draggable 小部件可以移动到任何其他小部件,而DragTarget 充当Draggable 小部件的接收器或放置位置。

    找到下面的代码示例,我使用它实现了一个简单的奇偶游戏

    该死,我是游戏开发者◕‿↼

    import 'package:flutter/material.dart';
    import 'dart:math';
    
    class OddOrEven extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _OddOrEvenState();
      }
    }
    
    class _OddOrEvenState extends State<OddOrEven> {
      bool accepted = false;
      Color dotColor = Colors.blue;
      GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();
    
      int val = 0;
      int score = 0;
    
      @override
      Widget build(BuildContext context) {
    
        // assign a random number to value which will be used as the box value
        val = Random().nextInt(100);
        return Scaffold(
          key: scaffoldKey,
          appBar: AppBar(),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
    
                // just a score and mock player name indicator
                Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Center(
                    child: Center(
                      child: Chip(
                        avatar: CircleAvatar(
                          backgroundColor: Colors.teal,
                          child: Text(
                            score.toString(),
                            style: TextStyle(color: Colors.white),
                          ),
                        ),
                        label: Text(
                          'Player Alpha',
                          style: TextStyle(
                              fontSize: 20.0,
                              color: Colors.black,
                              fontStyle: FontStyle.italic),
                        ),
                      ),
                    ),
                  ),
                ),
    
    
                // here comes our draggable.
                // it holds data which is our random number
                // the child of the draggable is a container reactangural in shape and 
                //
                Draggable(
                  data: val,
                  child: Container(
                    width: 100.0,
                    height: 100.0,
                    child: Center(
                      child: Text(
                        val.toString(),
                        style: TextStyle(color: Colors.white, fontSize: 22.0),
                      ),
                    ),
                    color: Colors.pink,
                  ),
    
                  // This will be displayed when the widget is being dragged
                  feedback: Container(
                    width: 100.0,
                    height: 100.0,
                    child: Center(
                      child: Text(
                        val.toString(),
                        style: TextStyle(color: Colors.white, fontSize: 22.0),
                      ),
                    ),
                    color: Colors.pink,
                  ),
                  // You can also specify 'childWhenDragging' option to draw
                  // the original widget changes at the time of drag.
    
                ),
    
    
                // and here this row holds our two DragTargets. 
                // One for odd numbers and the other for even numbers.
                //
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
    
                    Container(
                      width: 100.0,
                      height: 100.0,
                      color: Colors.green,
    
                      // Even holder DragTarget
                      //
                      child: DragTarget(
                        builder: (context, List<int> candidateData, rejectedData) {
                          print(candidateData);
                          return Center(
                              child: Text(
                            "Even",
                            style: TextStyle(color: Colors.white, fontSize: 22.0),
                          ));
                        },
    
                        // On will accept gets called just before it accepts the drag source.
                        // if needed, we can reject the data here. But we are not doing that as this is a GAME !!! :)
                        onWillAccept: (data) {
                          print("Will accpt");
                          return true; //return false to reject it
                        },
    
                        // On accepting the data by the DragTarget we simply check whether the data is odd or even and accept based on that and increment the counter and rebuild the widget tree for a new random number at the source.
                        onAccept: (data) {
                          print("On accpt");
                          if (data % 2 == 0) {
    
                            setState(() {
                              score++;
                            });
                            // How did you manage to score 3 points?
                            // Congrats. You won the game.
                            if (score >= 3) {
                              showDialog(
                                  context: context,
                                  builder: (BuildContext context) {
                                    return new AlertDialog(
                                      title: Text("Congrats!!"),
                                      content: Text("No-brainer...?"),
                                      actions: <Widget>[
                                        FlatButton(
                                          child: Text("Ok."),
                                          onPressed: () {
                                            Navigator.of(context).pop();
                                            setState(() {
                                              score = 0;
                                            });
                                          },
                                        )
                                      ],
                                    );
                                  });
                            }
                          } else {
                            setState(() {});
    
                          }
                        },
                      ),
                    ),
    
                    // And here is the Odd-holder
                    Container(
                      width: 100.0,
                      height: 100.0,
                      color: Colors.deepPurple,
                      child: DragTarget(
                        builder: (context, List<int> candidateData, rejectedData) {
                          return Center(
                              child: Text(
                            "Odd",
                            style: TextStyle(color: Colors.white, fontSize: 22.0),
                          ));
                        },
                        onWillAccept: (data) {
                          return true;
                        },
                        onAccept: (data) {
                          if (data % 2 != 0) {
    
                            setState(() {
                              score++;
                            });
    
                            if (score >= 10) {
                              showDialog(
                                  context: context,
                                  builder: (BuildContext context) {
                                    return new AlertDialog(
                                      title: Text("Congrats!!"),
                                      content: Text("No-brainer...?"),
                                      actions: <Widget>[
                                        FlatButton(
                                          child: Text("Thanks"),
                                          onPressed: () {
                                            Navigator.of(context).pop();
                                            setState(() {
                                              score = 0;
                                            });
                                          },
                                        )
                                      ],
                                    );
                                  });
                            }
                          } else {
                            setState(() {});
    
                          }
                        },
                      ),
                    )
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 对不起 - 我是个菜鸟。为了运行上述内容,我需要做什么?它需要一个 main() 函数,还是...?
    • @user3012629 请关注flutter.dev的开发介绍。 flutter.dev/docs/development/ui/widgets-intro TL;DR:在主函数内部,使用 runApp(OddOrEven());快速运行。
    【解决方案2】:

    如果您需要放置在非固定位置(无需 DragTarget 的 Draggable),这也可以通过 Stack()/Positioned() 使用渲染框大小来实现,根据 How to move element anywhere inside parent container with drag and drop in Flutter?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多