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

Draggable Widget
Draggable控件负责就是拖拽,父层使用了Draggable,它的子元素就是可以拖动的,子元素可以实容器,可以是图片。用起来非常的灵活。
参数说明:
- data: 是要传递的参数,在DragTarget里,会接受到这个参数。当然要在拖拽控件推拽到DragTarget的时候。
- child:在这里放置你要推拽的元素,可以是容器,也可以是图片和文字。
- feedback: 常用于反馈(设置)推拽元素时的样子,在案例中当推拽的时候,我们把它的颜色透明度变成了50%。当然你还可以改变它的大小。
- onDraggableCanceled:是当松开时的相应事件,经常用来改变推拽时到达的位置,改变时用setState来进行。
代码:
Draggable(data:widget.widgetColor,child: Container(width: 100,height: 100,color:widget.widgetColor,),feedback:Container(width: 100.0,height: 100.0,color: widget.widgetColor.withOpacity(0.5),),onDraggableCanceled: (Velocity velocity, Offset offset){setState(() {this.offset = offset;});},
DragTarget Widget
DragTarget是用来接收拖拽事件的控件,当把Draggable放到DragTarget里时,他会接收Draggable传递过来的值,然后用生成器改变组件状态。
- onAccept:当推拽到控件里时触发,经常在这里得到传递过来的值。
- builder: 构造器,里边进行修改child值。
DragTarget(onAccept: (Color color) {_draggableColor = color;}, builder: (context, candidateData, rejectedData) {return Container(width: 200.0,height: 200.0,color: _draggableColor,);}),
实例代码DEMO
主文件main.dart
import 'package:flutter/material.dart';import 'drag_drop.dart';void main() => runApp(new MyApp());class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,title:'Flutter Demo',theme:ThemeData(primarySwatch: Colors.blue),home:DraggableDemo());}}
drag_drop.dart 文件
import 'package:flutter/material.dart';import 'draggable_widget.dart';class DraggableDemo extends StatefulWidget {@override_DraggableDemoState createState() => _DraggableDemoState();}class _DraggableDemoState extends State<DraggableDemo> {Color _draggableColor = Colors.pink[50];@overrideWidget build(BuildContext context) {return Scaffold(body: Stack(children: <Widget>[DraggableWidget(offset: Offset(80.0, 80.0),widgetColor: Colors.tealAccent,),DraggableWidget(offset: Offset(180.0, 80.0),widgetColor: Colors.redAccent,),DraggableWidget(offset: Offset(280.0, 80.0),widgetColor: Colors.red[100],),Center(child: DragTarget(onAccept: (Color color) {_draggableColor = color;}, builder: (context, candidateData, rejectedData) {return Container(width: 200.0,height: 200.0,color: _draggableColor,);}),)],));}}
draggable_widget.dart 文件
import 'package:flutter/material.dart';class DraggableWidget extends StatefulWidget {final Offset offset;final Color widgetColor;const DraggableWidget({Key key, this.offset, this.widgetColor}): super(key: key);_DraggableWidgetState createState() => _DraggableWidgetState();}class _DraggableWidgetState extends State<DraggableWidget> {Offset offset = Offset(0.0, 0.0);@overridevoid initState() {super.initState();offset = widget.offset;}@overrideWidget build(BuildContext context) {return Positioned(left: this.offset.dx,top: this.offset.dy,child: Draggable(data: widget.widgetColor,child: Container(width: 100,height: 100,color: widget.widgetColor,),feedback: Container(width: 100.0,height: 100.0,color: widget.widgetColor.withOpacity(0.5),),onDraggableCanceled: (Velocity velocity, Offset offset) {setState(() {//这里可以做拖拽到拖拽区块时候的判断if (true) {this.offset = offset;}});},),);}}
JavaScript中的拖拽
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="https://code.jquery.com/jquery-3.3.1.min.js"></script></head><style>div {width: 100px;height: 100px;border: 1px solid red;float: left;border-left: 0;border-top: 0}img {width: inherit;height: inherit;}</style><body><div id="div1" class="q" ondragover="allowDrop(event)" ondrop="drop(event)"><img id="drag1"src="http://n.sinaimg.cn/sinakd10112/175/w1080h1495/20200326/f2ac-irkazzv3170145.jpg" draggable="true"ondragstart="drag(event)" width="200" height="200" /></div><div id="div2" ondragover="allowDrop(event)" ondrop="drop(event)"><img id="drag2"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"draggable="true" ondragstart="drag(event)" width="200" height="200" /></div></body></html><script>for (let i = 0; i < 10; i++) {// $("body").append("<div ondragover='allowDrop(event)' ondrop='drop(event)'></div>")var eDiv = document.createElement("div")eDiv.setAttribute('ondragover', 'allowDrop(event)')eDiv.setAttribute('ondrop', 'drop(event)')document.querySelector("body").append(eDiv)console.log(eDiv.attributes);}/*拖事件 图片1 设置图片允许拖动draggable="true"2 拖的时候保存数据(图片id)ev.dataTrasfer.setData('credential凭据',ev.target.id);放置事件 DIV1允许图片放置这里ondragover="allowDrop()"allowDrop里面是一个阻止浏览器默认操作function allowDrop(ev){ev.preventDefault();}2 放置图片时ondrop="drop(ev)"function drop(ev{ev.preventDefalut(); //阻止浏览器默认操作var data=ev.dataTransfer.getData('credential凭据');//获取前面保存的数据ev.target.appendChild(document.getElementById(data));// DIV追加子元素}*/var img, div;function drag(ev) {ev.dataTransfer.setData("credential凭据", ev.target.id);img = ev.target;}function allowDrop(ev) { ev.preventDefault(); }function drop(ev) {if (ev.target.nodeName == "DIV") {ev.preventDefault();iSrc = ev.target.src;var data = ev.dataTransfer.getData("credential凭据");ev.target.appendChild(document.getElementById(data));}else if (ev.target.nodeName == "IMG") {iSrc = img.src;img.src = ev.target.src;ev.target.src = iSrc;}// console.log(ev.tatrget);}</script>
