Flex拖放功能,这里讲述自定义的拖放功能实现
主要是由DragSource,DragManager,DragEvent来的实现,对应的包是mx.core.DragSource,mx.managers.DragManager,mx.events.DragEvent,
假设拖动组件A到组件B上,整个事件过程可描述为:
1.鼠标点击A组件 ---> 2.1 拖动组件A正进入组件B的一瞬间, ---> 2.2 拖动A到达组件B上)---> 3.鼠标放下
其对应的事件主要有:
1. MouseDown(MounseEvent),dragStart(DragEvent) MouseDown作用于组件A,这里可以使用DragManager对DragSource(组件A的相关数据)暂存,并且可以对被拖动的组件A进行 代理,产生可视化的拖动效果
--->2.1 dragEnter(DragEvent)
--->2.2 dragOver(DragEvent)
--->3. dragDrop(DragEvent),dragComplete(DragEvent)
下面是源代码:
MXML代码:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:my="ecolab.sgcl.flex.*" creationComplete="init();"> <mx:Script> <![CDATA[ import ecolab.sgcl.flex.BasicDataOfUIComp; import ecolab.sgcl.utils.Search; import mx.core.UIComponent; import mx.core.DragSource; import mx.managers.DragManager; import flash.events.*; import mx.events.DragEvent; private var comp:UIComponent = new UIComponent(); private var line:Sprite = new Sprite(); private var gc:Graphics = line.graphics; private var lineTmp:Sprite = new Sprite(); private var gcTmp:Graphics = lineTmp.graphics; private var arr:Array = new Array(); private var target:MButton; //拖放里找到最匹配的组件 private function init():void{ comp.name = "lineBase"; baseCanvas.addChildAt(comp,0); //直线:Line this.drawLine(btn2,btn3); this.drawLine(btn3,btn4); } private function drawLine(comp1:UIComponent, comp2:UIComponent):void { gc.lineStyle(2,0x00ffee,50); gc.moveTo(comp1.x+comp1.width,comp1.y+comp1.height/2); gc.lineTo(comp2.x, comp2.y+comp2.height/2); comp.addChild(line); } private function doDragEnter(evt:DragEvent):void { if (evt.dragSource.hasFormat("myDs")) { DragManager.acceptDragDrop(baseCanvas); } } private function doDragOver(evt:DragEvent):void { var dragBtn:MButton = evt.dragSource.dataForFormat("myDs") as MButton; var rX:int = evt.dragSource.dataForFormat("relativeX") as Number; var rY:int = evt.dragSource.dataForFormat("relativeY") as Number; var obj:Object = {x:evt.localX-rX, y:evt.localY-rY,name:dragBtn.name}; var childArr:Array = baseCanvas.getChildren(); var matchName:String = Search.matchByEuclidean(childArr,obj); if(matchName == null) return; target = baseCanvas.getChildByName(matchName) as MButton; gcTmp.clear(); gcTmp.lineStyle(2,0xffff00,50); Search.drawLineByXY(target.x, target.y, target.width, target.height, evt.localX-rX, evt.localY-rY, dragBtn.width, dragBtn.height, gcTmp); //gcTmp.moveTo(target.x,target.y); //gcTmp.lineTo(evt.localX,evt.localY); comp.addChild(lineTmp); } private function doDragDrop(event:DragEvent):void { trace(event.dragSource); trace(event.currentTarget); trace(event.target); var data:MButton = event.dragSource.dataForFormat("myDs") as MButton; var rX:int = event.dragSource.dataForFormat("relativeX") as Number; var rY:int = event.dragSource.dataForFormat("relativeY") as Number; data.x = event.localX-rX; //stageX data.y = event.localY-rY; gcTmp.clear(); //gc.clear(); gc.lineStyle(1,0x0099ff,1); Search.drawLineByXY(target.x, target.y, target.width, target.height, data.x, data.y, data.width, data.height, gc); //Draw a Line } ]]> </mx:Script> <mx:Canvas id="baseCanvas" x="50" y="50" cornerRadius="0.5" backgroundColor="#336699" width="500" height="600" dragEnter="doDragEnter(event)" dragDrop="doDragDrop(event)" dragOver="doDragOver(event)" > <my:MButton id="btn1" label="Button1" x="10" y="10" height="30" width="100"/> <my:MButton id="btn2" label="Button2" x="10" y="110" height="40" width="100"/> <my:MButton id="btn3" label="Button3" x="160" y="100" height="60" width="100"/> <my:MButton id="btn4" label="Button4" x="320" y="105" height="50" width="100"/> </mx:Canvas> </mx:Application> ActionScript3.0类代码: package ecolab.sgcl.flex { import mx.controls.Button; import flash.events.MouseEvent; import mx.managers.DragManager; import mx.core.DragSource; public class MButton extends Button { public function MButton() { super(); this.addEventListener(MouseEvent.MOUSE_DOWN,doDrag); } private function doDrag(evt:MouseEvent):void { var btn:MButton = evt.currentTarget as MButton; var ds:DragSource=new DragSource(); ds.addData(btn,"myDs"); ds.addData(evt.localX,"relativeX"); //鼠标相对目标组件的坐标 ds.addData(evt.localY,"relativeY"); var cpyBtn:MButton=new MButton(); cpyBtn.width = btn.width; cpyBtn.height= btn.height; cpyBtn.label = btn.label; cpyBtn.setStyle("color","#AA6633"); DragManager.doDrag(this,ds,evt,cpyBtn); //cpyBtn是被拖动组件的代理 //Flex中任何可视控件都可作为代理。 } } }
上述环境:
windowXp sp3
Eclipse3.2 + Flex SDK3 + FlexBuilder3.0 Plugin + IE7.0