Flutter提供了强大的拖拽控件,可以灵活定制,并且非常简单。这节课就学习一下Flutter拖拽控件,并根据学到的知识作一个拖拽案例>

Draggable控件实例 - 图1

Draggable Widget

Draggable控件负责就是拖拽,父层使用了Draggable,它的子元素就是可以拖动的,子元素可以实容器,可以是图片。用起来非常的灵活。
参数说明:

  • data: 是要传递的参数,在DragTarget里,会接受到这个参数。当然要在拖拽控件推拽到DragTarget的时候。
  • child:在这里放置你要推拽的元素,可以是容器,也可以是图片和文字。
  • feedback: 常用于反馈(设置)推拽元素时的样子,在案例中当推拽的时候,我们把它的颜色透明度变成了50%。当然你还可以改变它的大小。
  • onDraggableCanceled:是当松开时的相应事件,经常用来改变推拽时到达的位置,改变时用setState来进行。

代码:

  1. Draggable(
  2. data:widget.widgetColor,
  3. child: Container(
  4. width: 100,
  5. height: 100,
  6. color:widget.widgetColor,
  7. ),
  8. feedback:Container(
  9. width: 100.0,
  10. height: 100.0,
  11. color: widget.widgetColor.withOpacity(0.5),
  12. ),
  13. onDraggableCanceled: (Velocity velocity, Offset offset){
  14. setState(() {
  15. this.offset = offset;
  16. });
  17. },

DragTarget Widget

DragTarget是用来接收拖拽事件的控件,当把Draggable放到DragTarget里时,他会接收Draggable传递过来的值,然后用生成器改变组件状态。

  • onAccept:当推拽到控件里时触发,经常在这里得到传递过来的值。
  • builder: 构造器,里边进行修改child值。
    1. DragTarget(onAccept: (Color color) {
    2. _draggableColor = color;
    3. }, builder: (context, candidateData, rejectedData) {
    4. return Container(
    5. width: 200.0,
    6. height: 200.0,
    7. color: _draggableColor,
    8. );
    9. }),

    实例代码DEMO

    主文件main.dart

    1. import 'package:flutter/material.dart';
    2. import 'drag_drop.dart';
    3. void main() => runApp(new MyApp());
    4. class MyApp extends StatelessWidget {
    5. @override
    6. Widget build(BuildContext context) {
    7. return MaterialApp(
    8. debugShowCheckedModeBanner: false,
    9. title:'Flutter Demo',
    10. theme:ThemeData(
    11. primarySwatch: Colors.blue
    12. ),
    13. home:DraggableDemo()
    14. );
    15. }
    16. }

drag_drop.dart 文件

  1. import 'package:flutter/material.dart';
  2. import 'draggable_widget.dart';
  3. class DraggableDemo extends StatefulWidget {
  4. @override
  5. _DraggableDemoState createState() => _DraggableDemoState();
  6. }
  7. class _DraggableDemoState extends State<DraggableDemo> {
  8. Color _draggableColor = Colors.pink[50];
  9. @override
  10. Widget build(BuildContext context) {
  11. return Scaffold(
  12. body: Stack(
  13. children: <Widget>[
  14. DraggableWidget(
  15. offset: Offset(80.0, 80.0),
  16. widgetColor: Colors.tealAccent,
  17. ),
  18. DraggableWidget(
  19. offset: Offset(180.0, 80.0),
  20. widgetColor: Colors.redAccent,
  21. ),
  22. DraggableWidget(
  23. offset: Offset(280.0, 80.0),
  24. widgetColor: Colors.red[100],
  25. ),
  26. Center(
  27. child: DragTarget(onAccept: (Color color) {
  28. _draggableColor = color;
  29. }, builder: (context, candidateData, rejectedData) {
  30. return Container(
  31. width: 200.0,
  32. height: 200.0,
  33. color: _draggableColor,
  34. );
  35. }),
  36. )
  37. ],
  38. ));
  39. }
  40. }

draggable_widget.dart 文件

  1. import 'package:flutter/material.dart';
  2. class DraggableWidget extends StatefulWidget {
  3. final Offset offset;
  4. final Color widgetColor;
  5. const DraggableWidget({Key key, this.offset, this.widgetColor})
  6. : super(key: key);
  7. _DraggableWidgetState createState() => _DraggableWidgetState();
  8. }
  9. class _DraggableWidgetState extends State<DraggableWidget> {
  10. Offset offset = Offset(0.0, 0.0);
  11. @override
  12. void initState() {
  13. super.initState();
  14. offset = widget.offset;
  15. }
  16. @override
  17. Widget build(BuildContext context) {
  18. return Positioned(
  19. left: this.offset.dx,
  20. top: this.offset.dy,
  21. child: Draggable(
  22. data: widget.widgetColor,
  23. child: Container(
  24. width: 100,
  25. height: 100,
  26. color: widget.widgetColor,
  27. ),
  28. feedback: Container(
  29. width: 100.0,
  30. height: 100.0,
  31. color: widget.widgetColor.withOpacity(0.5),
  32. ),
  33. onDraggableCanceled: (Velocity velocity, Offset offset) {
  34. setState(() {
  35. //这里可以做拖拽到拖拽区块时候的判断
  36. if (true) {
  37. this.offset = offset;
  38. }
  39. });
  40. },
  41. ),
  42. );
  43. }
  44. }

JavaScript中的拖拽

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  9. </head>
  10. <style>
  11. div {
  12. width: 100px;
  13. height: 100px;
  14. border: 1px solid red;
  15. float: left;
  16. border-left: 0;
  17. border-top: 0
  18. }
  19. img {
  20. width: inherit;
  21. height: inherit;
  22. }
  23. </style>
  24. <body>
  25. <div id="div1" class="q" ondragover="allowDrop(event)" ondrop="drop(event)"><img id="drag1"
  26. src="http://n.sinaimg.cn/sinakd10112/175/w1080h1495/20200326/f2ac-irkazzv3170145.jpg" draggable="true"
  27. ondragstart="drag(event)" width="200" height="200" /></div>
  28. <div id="div2" ondragover="allowDrop(event)" ondrop="drop(event)"><img id="drag2"
  29. src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1585323091847&di=552aae10f464e9ca90e91920c450060e&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20171120%2F5bbe5a3c8b26408095e60d8f8af0d239.jpeg"
  30. draggable="true" ondragstart="drag(event)" width="200" height="200" /></div>
  31. </body>
  32. </html>
  33. <script>
  34. for (let i = 0; i < 10; i++) {
  35. // $("body").append("<div ondragover='allowDrop(event)' ondrop='drop(event)'></div>")
  36. var eDiv = document.createElement("div")
  37. eDiv.setAttribute('ondragover', 'allowDrop(event)')
  38. eDiv.setAttribute('ondrop', 'drop(event)')
  39. document.querySelector("body").append(eDiv)
  40. console.log(eDiv.attributes);
  41. }
  42. /*
  43. 拖事件 图片
  44. 1 设置图片允许拖动
  45. draggable="true"
  46. 2 拖的时候保存数据(图片id)
  47. ev.dataTrasfer.setData('credential凭据',ev.target.id);
  48. 放置事件 DIV
  49. 1允许图片放置这里
  50. ondragover="allowDrop()"
  51. allowDrop里面是一个阻止浏览器默认操作
  52. function allowDrop(ev){
  53. ev.preventDefault();
  54. }
  55. 2 放置图片时
  56. ondrop="drop(ev)"
  57. function drop(ev{
  58. ev.preventDefalut(); //阻止浏览器默认操作
  59. var data=ev.dataTransfer.getData('credential凭据');//获取前面保存的数据
  60. ev.target.appendChild(document.getElementById(data));// DIV追加子元素
  61. }
  62. */
  63. var img, div;
  64. function drag(ev) {
  65. ev.dataTransfer.setData("credential凭据", ev.target.id);
  66. img = ev.target;
  67. }
  68. function allowDrop(ev) { ev.preventDefault(); }
  69. function drop(ev) {
  70. if (ev.target.nodeName == "DIV") {
  71. ev.preventDefault();
  72. iSrc = ev.target.src;
  73. var data = ev.dataTransfer.getData("credential凭据");
  74. ev.target.appendChild(document.getElementById(data));
  75. }
  76. else if (ev.target.nodeName == "IMG") {
  77. iSrc = img.src;
  78. img.src = ev.target.src;
  79. ev.target.src = iSrc;
  80. }
  81. // console.log(ev.tatrget);
  82. }
  83. </script>

附件

Draggable拖拽控件实例-lib.zip