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