Flex中的拖动技术
? ?Flex中的拖动技术 ? ? 网上发现这篇文章很详细,稍作补充整理下! 组件的拖动分为:加强型(即本身就可以拖动设置是否可以拖动的属性即可),非加强型(可以通过DragManager,DragEvent,DragSource三个类来实现) 下面详细讲解常见的拖动,案例比较多,可以自行类推和拓展! <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" fontSize="12"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.core.IUIComponent; import mx.events.DragEvent; import mx.core.DragSource; import mx.managers.DragManager; [Bindable] private var listData:ArrayCollection = new ArrayCollection(); //拖动初始器 private function dragSource(myData:String,e:MouseEvent,format:String):void { var iu:IUIComponent = e.currentTarget as IUIComponent; var ds : DragSource = new DragSource(); ds.addData(myData,format);//设置一个标号format DragManager.doDrag(iu,ds,e); // 开始拖动这个物体 } //当拖进去时 private function onEnter( e:DragEvent,format:String ) : void { if(e.dragSource.hasFormat(format))//如果标号为format则接受拖来的物体 { DragManager.acceptDragDrop(IUIComponent(e.target) );// 接受被拖进来的物体 } } //当拖完成时 private function onDrop(e:DragEvent,format:String) : void { var myData:Object = new Object(); myData = e.dragSource.dataForFormat(format); list1.dataProvider.addItem(myData);//list1是List的id,要是扩展到其他组件,改这里就可以了。 } ]]> </mx:Script> <mx:Label text="拖动我到List" width="86" height="27" id="lbl" mouseDown="dragSource('这个是一个label',event,'stringFormat')"/> <mx:List dataProvider="{listData}" id="list1" dragEnter="onEnter(event,'stringFormat')" dragDrop="onDrop(event,'stringFormat')" width="206"> </mx:List> <!--文档注释--> </mx:Application> Flex组件内置了处理拖拽事件的接口,有些控件已经实现了拖拽功能,比如List、DataGrid、Menu、
mouseDown:鼠标按下。 接收方也将经历几个阶段 1.?? Tree与Tree之间的拖动: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle"> <mx:XML id="myData"> <data> <item label="ActionScript"> <item label="Flash"/> <item label="Flex"/> </item> <item label="Mirage"> </item> <item label="JavaScript"/> </data> </mx:XML> <mx:XML id="copyData"> <data> <item label="JavaScript"/> </data> </mx:XML> <mx:Tree dropEnabled="true" dragEnabled="true" dragMoveEnabled="true" allowMultipleSelection="true" dataProvider="{myData.item}" labelField="@label"/> <mx:Tree dropEnabled="true" dataProvider="{copyData.item}" labelField="@label"/> </mx:Application>
上面代码中只需设置
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" fontSize="12"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.events.DragEvent; [Bindable] private var mylist:ArrayCollection; //当拖完成时 private function onDrop(e:DragEvent):void { var myData:Object=new Object(); myData=e.dragSource.dataForFormat('items'); //从dragSource中拿到条目 var name:String=myData[0].name; //注意这个地方必需要用变量进行替换 list1.dataProvider.addItem(name); e.preventDefault(); //可以去掉默认的数据转移 } ]]> </mx:Script> <mx:XMLList id="employees"> <employee> <name>小马</name> <phone>13042334532</phone> <email>liuhai@163.com</email> </employee> <employee> <name>张春</name> <phone>13642987532</phone> <email>zhang@sina.com</email> </employee> <employee> <name>小李</name> <phone>13923485844</phone> <email>xiaoli@qq.com</email> </employee> </mx:XMLList> <mx:DataGrid x="10" y="15" width="277" id="dg" rowCount="5" dataProvider="{employees}" dragEnabled="true"> <mx:columns> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Email" dataField="email"/> <mx:DataGridColumn headerText="Phone" dataField="phone"/> </mx:columns> </mx:DataGrid> <mx:DataGrid dropEnabled="true"> <mx:columns> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Email" dataField="email"/> <mx:DataGridColumn headerText="Phone" dataField="phone"/> </mx:columns> </mx:DataGrid> <mx:List height="210" width="206" id="list1" dropEnabled="true" dataProvider="{mylist}" dragDrop="onDrop(event)"> </mx:List> </mx:Application> 2.非加强拖动技术
Button的拖动,可以扩展到其他组件 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" fontSize="12"> <mx:Script> <![CDATA[ import mx.core.IUIComponent; import mx.events.DragEvent; import mx.core.DragSource; import mx.managers.DragManager; //拖动初始器 private function dragSource(e:MouseEvent,format:String):void { var iu:IUIComponent=e.currentTarget as IUIComponent; var ds:DragSource=new DragSource(); ds.addData({"x": e.localX,"y": e.localY},format); //设置一个标号format DragManager.doDrag(iu,e); } //当拖进去时 private function onEnter(e:DragEvent,format:String):void { if (e.dragSource.hasFormat(format)) //如果标号为format则接受拖来的物体 { DragManager.acceptDragDrop(IUIComponent(e.target)); } } //当拖完成时 private function onDrop(e:DragEvent,format:String):void { var myData:Object=new Object(); myData=e.dragSource.dataForFormat(format); btn.x=this.mouseX - myData.x; //btn为按钮的id,要是扩展到其他组件,改这里就可以了。 btn.y=this.mouseY - myData.y; } ]]> </mx:Script> <mx:Canvas y="40" id="cansAccess" backgroundColor="#000000" width="300" height="200" dragEnter="onEnter(event,'formatString')" dragDrop="onDrop(event,'formatString')"/> <mx:Button id="btn" label="拖动我到面板" mouseDown="dragSource(event,'formatString')"/> </mx:Application>
一定要注意,标签的先后位置,Button 要在Canvas 之后.
? <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12"> <mx:Script> <![CDATA[ import mx.containers.Box; import mx.containers.Canvas; import mx.core.IUIComponent; import mx.events.DragEvent; import mx.managers.DragManager; import mx.core.DragSource; //拖动初始器 private function dragSource(e:MouseEvent,format:String):void { var iu:IUIComponent=e.currentTarget as IUIComponent; var ds:DragSource=new DragSource(); ds.addData(iu,e); // 开始拖动这个物体 } //当拖进去时 private function onEnter(e:DragEvent,format:String):void { if (e.dragSource.hasFormat(format)) //如果标号为format则接受拖来的物体 { DragManager.acceptDragDrop(IUIComponent(e.target)); // 接受被拖进来的物体 } } //当拖完成时 private function onDrop(e:DragEvent,format:String):void { var box:Box=Box(e.dragInitiator); //如果扩展到其他组件,改这里Box就可以了。 box.x=e.localX; box.y=e.localY; } ]]> </mx:Script> <mx:Canvas backgroundColor="0xEEEEEE" width="500" height="246" horizontalCenter="0" verticalCenter="0" dragEnter="onEnter(event,'boxFormat')" dragDrop="onDrop(event,'boxFormat')"> <mx:Box id="boxDrag" width="20" height="20" backgroundColor="0x00FFCC" x="97" y="47" mouseDown="dragSource(event,'boxFormat');"> </mx:Box> </mx:Canvas> </mx:Application>
4.图片的拖动 ? <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%" fontSize="12"> <mx:Script> <![CDATA[ private var oldX:Number; //拖动开始是的坐标 private var oldY:Number; //拖动开始 private function dragStart(event:MouseEvent):void { oldX=event.stageX; //相对Application的坐标 oldY=event.stageY; } //拖动结束 private function dragEnd(event:MouseEvent):void { lbl.text="Local (x,y):" + event.localX.toString() + "," + event.localX.toString(); //相对图片的坐标 lbl2.text="Stage (x,y):" + event.stageX.toString() + "," + event.stageY.toString(); //相对Application的坐标 if (event.buttonDown) { //如果鼠标在移动过程中并且按下,也就是说鼠标的拖动事件。 var x:Number=event.stageX - oldX; //相对Application的坐标的移动量 var y:Number=event.stageY - oldY; oldX=event.stageX; //更新拖动开始是的坐标 oldY=event.stageY; img.move(img.x + x,img.y + y); //img是 Image的id,如果扩展到其他组件,改这里就可以了。 } } ]]> </mx:Script> <mx:Label x="10" y="10" text="" id="lbl"/> <mx:Label x="10" y="27" text="" id="lbl2"/> <mx:Panel x="257" y="71" width="700" height="80%" layout="absolute" horizontalScrollPolicy="off" verticalScrollPolicy="off" title="图片在面板中的拖动例子" fontSize="12"> <mx:Image id="img" x="0" y="0" source="test.JPG" mouseMove="dragEnd(event)" mouseDown="dragStart(event)"/> </mx:Panel> </mx:Application>
5.从外部拖动到组件,比如从桌面上拖动一个图片到图片组件等。 拖动外部文件 ? <mx:Canvas y="40" id="cansAccess" backgroundColor="#000000" width="300" height="200"
dragDrop="complete(event)" nativeDragDrop="nativeComplete(event)" dragEnter="enter(event)" />
<mx:Button id="btnDrag" label="拖动我"
mouseDown="doDrag( event )" />
按理来说当拖动内部控件的时候会触发dragDrop事件,拖动外部文件会触发nativeDragDrop事件,事实上,不管你拖动外部文件还是内部控件都会触发这两个事件。这里我们使用Clipboard来解决这一麻烦
private function doDrag( e : MouseEvent ) : void { var ds : DragSource = new DragSource; ds.addData( {"x" : e.localX,"y" : e.localY},"xy"); DragManager.doDrag(btnDrag,e); } private function enter( e :DragEvent ) : void { DragManager.acceptDragDrop( Canvas(e.target) ); NativeDragManager.acceptDragDrop(Canvas(e.target)); //使其接受从外部拖进来的文件 } private function complete( e : DragEvent ) : void { } private function nativeComplete( e : NativeDragEvent ) : void { var filesObj : Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT ) as Array; //获取剪切板上的文件列表 if( filesObj && filesObj.length > 0) //符合这一条件说明是从外部拖文件进来 这里假设处理拖进来的是图片 { for each( var item : File in filesObj ) { switch( item.extension ) { case "jpg": case "bmp": case "gif": var img : Image = new Image; img.source = item.nativePath; cansAccess.addChild( img ); break; } } } else //否则的话是就是在拖动内部的控件 { var xy : Object = e.clipboard.getData(e.clipboard.formats[0]); //还记得doDrag 的时候附加的那个 DragSource 么? //这里因为不能用e.dragSource.dataForFormat("xy")了因为事件不一样, //但我们还是可以用剪切板来取得这个值 btnDrag.x = e.localX - xy.x + cansAccess.x; btnDrag.y = e.localY - xy.y + cansAccess.y; } }
3.点击Finish,在自动创建的MXML文件中,敲入以下代码: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:containers="dNdLib.containers.*" fontSize="12"> <mx:Script> <![CDATA[ import dNdLib.managers.DnDManager; ]]> </mx:Script> <containers:DnDContainer borderStyle="solid" id="left" backgroundColor="#FFFFFF" width="161" height="237" x="110" y="168"> <mx:Button label="拖动我" mouseDown="DnDManager.getInstance().doDrag(event)" width="92" height="32"/> <mx:CheckBox label="拖动就这么简单" mouseDown="DnDManager.getInstance().doDrag(event)"/> </containers:DnDContainer> <containers:DnDContainer borderStyle="solid" id="bottom" backgroundColor="#FFFFFF" x="415" y="168" width="140" height="237"/> </mx:Application> 然后Run一下看看结果吧,组件可以拖动了。很简单吧。 注意:必须为DnDContainer设置一个背景色(backgroundColor=color),否则可能无法产生相应区域。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |