Flutter拖拽控件Draggable
Draggable
最近做了一个Flutter项目,其中有一个需求是做出三个可以互相拖拽的任务列表,平时在做Android项目时,拖动的控件基本上都是自定义View来实现的,想看看在Fluter上大家都是怎么实现的,没想到flutter提供了一个非常方便的拖拽控件Draggable。
Draggable的构造函数
我个人在Flutter开发时,遇到没有见过的控件时,点开源码观察它的构造函数一定是了解它的功能的最优解,我们看Draggable的构造函数:
const Draggable({Key key,@required this.child, // child不用解释了吧@required this.feedback, // 拖动时显示的组件this.data, // 控件携带的数据(一般提供给DragTarget,后面会讲)this.axis, // 对滑动的方向做限制(横向或者纵向)this.childWhenDragging, //多点触控拖动时显示的组件this.feedbackOffset = Offset.zero, // 拖动后显示的位置,默认(0,0)this.dragAnchor = DragAnchor.child, // 开始拖动时feedback显示的位置(原child位置还是触摸的位置)this.affinity, // 让Draggable可以共享垂直或水平方向上的滑动事件(例如拖动同时滚动Scrollable)this.maxSimultaneousDrags, // 多点触控时最大响应数this.onDragStarted, // 开始拖动时的回调this.onDraggableCanceled, // 未拖动到DragTarget控件上时回调this.onDragEnd, // 拖动结束时的回调this.onDragCompleted, // 拖动到DragTarget控件上时回调this.ignoringFeedbackSemantics = true, // 控制是否显示feedback}) : assert(child != null),assert(feedback != null),assert(ignoringFeedbackSemantics != null),assert(maxSimultaneousDrags == null || maxSimultaneousDrags >= 0),super(key: key);
可以看到Draggable还是很强大的,把拖动时显示的weiget也给封装好了,我们只用传入一个weiget就能自动显示,对拖拽事件的回调也很丰富,其中的DragTarget是另一个跟Draggable搭配的强大控件,下面先实现一个简单的Draggable:
Draggable的实现
Container(alignment: Alignment.center,child: Draggable(child: Text("我可以被拖动!"),feedback: Text("我正在被拖动!"),),),
是不是很简单,我们可以加一点其他的属性,比如对水平拖动进行限制
Container(alignment: Alignment.center,child: Draggable(axis: Axis.vertical,child: Text("我可以被拖动!"),feedback: Text("我正在被拖动!"),),),
DragTarget
但是一般我们的拖动逻辑都是将一个控件挪到指定的位置(或者控件)上,以往我们都是通过拖动后的坐标等方法判断,然而观察Draggable的回调发现还有一个与Draggable配套的控件DragTarget,用DragTarget就可以把拖动到指定位置上的判断交给系统判断,话不多说,放码过来
DragTarget的构造函数
const DragTarget({Key key,@required this.builder, // 构造器this.onWillAccept, // 判断该数据是否符合要求this.onAccept, // 接收 Data 数据的回调this.onLeave, // }) : super(key: key);
DragTarget的构造函数就简单许多了:
builder:构造器;
其中参数包括三个属性,分别为 context
上下文环境,candidateData
为 onWillAccept 回调为 true 时可接收的数据列表,rejectedData
为 onWillAccept 回调为 false 时拒绝时的数据列表;builder的返回值就是DragTarget的child
typedef DragTargetBuilder<T> = Widget Function(BuildContext context, List<T> candidateData, List<dynamic> rejectedData);
onWillAccept:Draggable拖拽到 DragTarget 时的回调
用于判断该数据是否符合要求,返回true 时会将 Data 数据添加到 candidateData 列表中,且会调用onAccept;false 时会将 Data 数据添加到 rejectedData 列表中,且不会调用onAccept;
onAccept:用于接收Draggable中Data数据的回调;
onLeave:为Draggable离开时的回调;
DragTarget的实现
String data = "默认数据";@overrideWidget build(BuildContext context) {return Container(padding: EdgeInsets.only(top: 200),color: Colors.white,child: Column(children: [Draggable<String>(data: "Draggable数据",,child: Text("我可以被拖动!"),feedback: Text("我正在被拖动!"),),DragTarget<String>(builder: (BuildContext context, List<dynamic> accepted, List<dynamic> rejected,) {return Text(data);},onAccept: (data) {setState(() {this.data = data;});},)],),);}
同理,我们可以应用到更复杂的画面中,还记得我一开始的需求么:做出三个可以互相拖拽的任务列表,于是我们可以将DragTarget和Draggable结合起来,将list的item做为Draggable,将每个list作为DragTarget,加上亿点点细节:
List<String> list1 = ["list1_1", "list1_2", "list1_3"];List<String> list2 = ["list2_1", "list2_2"];List<String> list3 = ["list3_1", "list3_2"];@overrideWidget build(BuildContext context) {return Container(padding: EdgeInsets.only(top: 200),color: Colors.white,child: Column(children: [_createListView(list1),_createListView(list2),_createListView(list3),],),);}Widget _createListView(List<String> _items) {return DragTarget<String>(builder: (BuildContext context,List<dynamic> accepted,List<dynamic> rejected,) {return ListView.builder(itemCount: _items.length,shrinkWrap: true,padding: EdgeInsets.all(10),itemBuilder: (context, index) {return Draggable<String>(onDragCompleted: () {// 在拖动到DragTarget后删除数据setState(() {_items.removeAt(index);});},feedback: Material(child: Container(height: 60,width: 200,color: Colors.blueAccent,alignment: Alignment.center,child: Text(_items[index],style: TextStyle(color: Colors.white),),),),data: _items[index],child: Container(height: 50,width: 200,color: Colors.blueAccent,alignment: Alignment.center,child: Text(_items[index],style: TextStyle(color: Colors.white, fontSize: 20),),),);},);},onAccept: (String data) {setState(() {// 添加Draggable数据到list_items.add(data);});},);}
搞定!
Flutter拖拽控件Draggable相关推荐
- winform窗体自由拖拽控件
源码地址:https://download.csdn.net/download/horseroll/10906640 以上链接是用积分下载的,如果没有积分,可以用以下链接付费下载:https://do ...
- Silverlight 游戏开发:可重用的拖拽控件
游戏中有各种各样的拖拽需求,大到窗口,小到图标,在游戏界面操作中,点击和拖拽占据了用户操作的大部分行为,如何做好一个拖拽控件至关重要,做一个可重用的拖拽控件更加重要,我的这些实现方法可能比较另类,但只 ...
- .net中实现拖拽控件
在.net中实现拖拽控件主要用到以下函数: MouseDown(object sender, MouseEventArgs e) MouseUp(object sender, MouseEventAr ...
- js 拖拽生成html,js拖拽插件 js 拖拽控件生成自定义表单 怎么实现
想请教一个js的问题,拖拽控件 js 拖拽控件生成自定义表单 怎么实现 说说步骤吧 监听mousedown事件 - 获取鼠标点击元素,判断是否可拖拽 - 设置flag做标记 - 建一个tempDOM, ...
- vue拖拽控件生成界面代码_Blue HMI人机界面开发平台
随着信息技术在军工.制造业等领域的不断普及和快速发展,各行业信息系统软件的研制正在由传统的重复.烟囱式开发模式向以系统顶层设计为指导,以标准化.组件化.集成化软件开发为重点的模式逐步转变. ...
- H5实现多图片预览上传,可点击可拖拽控件介绍
在做图片上传时发现一个蛮好用的控件,支持多张图片同时上传,可以点击选择图片,也可以将图片拖拽到上传框直接上传,方便,好用,接口也简单,基本可以直接放到项目里使用. 先看看他的样式: 选择图片后: $( ...
- C# Winform平台下实现自由拖拽控件
C#控件拖动 1.场景需求 有时候,我们在编写PC上位机软件的时候,不免需要将所定义的控件可以自由的拖拽到任意地方.为了实现此一需求,我尝试了很多种方法,比如使用Mouse_Leave,Mouse_D ...
- Android 拖拽控件交换位置
距离上次写博客已快有一月,中间也动过几次写博客的心思,但却因为懒,耽搁了下来. --萧洛 在网上搜寻了许久,实在是没有找到可用的demo,无奈只好自己写 ...
- android 嵌套分组拖动_GitHub - Mosect/DragLayout: Android拖拽控件,支持上下左右滑动、折叠或者嵌套ListView、RecyclerView等...
DragLayout Android拖拽布局,包括以下布局: DragLayout 基础布局类 FlowLayout 可折叠布局,继承DragLayout DragRefreshLayout 拖拽刷新 ...
最新文章
- arduino与DS1302时钟调试失败的分析
- 一个悄然成为世界最流行的操作系统诞生!
- 【Spring Cloud】Redis缓存接入监控、运维平台CacheCloud
- 【ArcGIS风暴】如何将矢量数据(点、线、面)折点坐标转为GeoJSON格式?
- java泛型程序设计——约束与局限性
- 水面反光如何拍摄_拍摄水面反射的创意
- nll_loss 和 cross_entropy
- 用 Python 写出这样的进度条,刷新了我对进度条的认知
- stm32 vscode 编译_vs code+gcc stm32编译环境搭建
- storm之topology的启动
- DropdownList获取ID方法
- 推荐系统实践---第一章:好的推荐系统
- 愤怒!竟然还有学校还在教 Java 的 Swing
- 使用JSONRPC操作附带token(secret)的aria2
- JavaProperties文件操作
- xshell命令:cd进入指定(目标路径)文件夹 - 解说篇
- JTS Java空间几何计算、距离、最近点、subLine等计算
- lambda表达式的分析及使用
- eplan实战设计pdf百度云_EPLAN实战设计
- 计算机教室是使用计划书,教师个人计算机学习计划书_老师计算机学习计划范文...