Flex拖動實現方法
在互動性要求較高的系統中,拖動是一種比較常用的技術,例如,我們經常用到許可權定製、資料匯入匯出定製等功能,這種情況下,一般是目標資料集合已經確定,使用者需要從已有的集合中選擇條目,使用拖動完成實現起來比較直觀,友好;有些場景下需要允許容器內的元素能夠自由拖動,例如一些圖形設計工具。在Flex中,它本身就提供了很多支援拖動的特性,很多情況下,這些特效能夠簡化我們的開發,但是也有一些情況是需要我們自定義實現的。本文介紹了三種flex中進行拖動的方法。
方法一:List中資料的拖動
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:List dragEnabled="true" width="162" labelField="Name">
<mx:Array>
<mx:Object Name="Item a"/>
<mx:Object Name="Item b"/>
<mx:Object Name="Item c"/>
</mx:Array>
</mx:List>
<mx:List dropEnabled="true" x="196" y="0" width="171" labelField="Name">
</mx:List>
</mx:Application>
通過指定List的dragEnabled=true來允許List控制元件資料支援拖動,指定dropEnabled=true來允許List控制元件支援接受拖動資料。
方法二:容器中控制元件的拖動
這種方式下控制元件的拖動有兩種方法,一種是利用Flex自身的實現,一種是使用自定義的實現。對於Flex內的所有可視控制元件,都支援startDrag()和stopDrag()方法,我們通過定製相應的事件即可完成拖動的操作。例如:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
private function start(e:MouseEvent):void
{
var component:UIComponent=e.currentTarget as UIComponent
component.startDrag();
}
private function stop(e:MouseEvent):void
{
var component:UIComponent=e.currentTarget as UIComponent
component.stopDrag();
}
]]>
</mx:Script>
<mx:Canvas x="0" y="0" width="100%" height="100%">
<mx:Button x="237" y="69" label="Button" mouseDown="start(event)" mouseUp="stop(event)"/>
<mx:CheckBox x="424" y="49" label="Checkbox" mouseDown="start(event)" mouseUp="stop(event)"/>
<mx:Image x="344" y="138" mouseDown="start(event)" mouseUp="stop(event)"/>
<mx:Label x="267" y="233" text="Label" mouseDown="start(event)" mouseUp="stop(event)"/>
<mx:TextInput x="412" y="196" mouseDown="start(event)" mouseUp="stop(event)"/>
</mx:Canvas>
</mx:Application>
第二種方法就是自定義拖動的實現,主要的原理就是:在控制元件mouseDown之後,給所處的container註冊mouseMove和mouseUp事件及處理函式;mouseMove的時候計算滑鼠移動的值,然後將控制元件座標做相應的改變,mouseUp的時候移除mouseMove和mouseUp處理函式。
程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="flowdesigner.*" creationComplete="init()">
<mx:Script>
<![CDATA[
import flowdesigner.ActivityNode;
import ui.action.ObjectHandles;
private var mouseDownPosition:Point=null;
private function init():void
{
toDrag.addEventListener(MouseEvent.MOUSE_DOWN,componentMouseDownHandler);
}
public function componentMouseDownHandler(e:MouseEvent):void
{
container.stage.addEventListener(MouseEvent.MOUSE_MOVE,containerMouseMoveHandler);
container.stage.addEventListener(MouseEvent.MOUSE_UP,containerMouseUpHandler);
mouseDownPosition=new Point(e.stageX,e.stageY);
}
public function containerMouseMoveHandler(e:MouseEvent):void
{
var currentPoint:Point=container.globalToLocal(new Point(e.stageX,e.stageY));
var temp:Point=container.globalToLocal(mouseDownPosition);
var transation_x:int=currentPoint.x-temp.x;
var transation_y:int=currentPoint.y-temp.y;
toDrag.x=mouseDownPosition.x+transation_x;
toDrag.y=mouseDownPosition.y+transation_y;
}
public function containerMouseUpHandler(e:MouseEvent):void
{
container.stage.removeEventListener(MouseEvent.MOUSE_MOVE,containerMouseMoveHandler);
container.stage.removeEventListener(MouseEvent.MOUSE_UP,containerMouseUpHandler);
}
]]>
</mx:Script>
<ns1:DrawCanvas id="container" width="100%" height="100%" backgroundColor="#FFFDFD">
<mx:Canvas id="toDrag" width="121" height="82" backgroundColor="#BA8080"/>
</ns1:DrawCanvas>
</mx:Application>
Init中給需要拖動的控制元件註冊mouseDown處理函式;滑鼠按下的時候給容器註冊mouseMove和mouseUp處理函式,同時記錄初始座標值;mouseMove的時候,將當前事件座標值和原始座標值分別轉換為容器中相對座標值,然後計算x、y座標軸上的相對移動距離,最後設定控制元件座標值;mouseUp時取消相應的事件處理。
方法三:自定義拖動
這種方式一般能夠滿足大多數的情景,通過DragManager自己實現dragEnter,dragDrop事件來完成拖動功能。
DragManager 類管理拖放操作。當用戶使用滑鼠選擇某個專案時,所選元件稱為拖動啟動器。拖動操作期間顯示的影象稱為拖動代理。當用戶將拖動代理移動到其它元件時,系統會向該元件傳送 dragEnter 事件。如果該元件接受拖動,即可成為拖放目標,並接收 dragOver、dragExit 和 dragDrop 事件。拖動操作完成後,會向拖動啟動器傳送 dragComplete 事件。DragSource 類中包含正被拖動的資料。
程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import mx.core.DragSource;
import mx.managers.DragManager;
import mx.controls.Image;
import mx.events.DragEvent;
private function beginDrag(e:MouseEvent):void
{
var img:Image=e.currentTarget as Image;
var dragImg:Image=new Image();
dragImg.source=img.source;
var ds:DragSource=new DragSource();
ds.addData(img,"dragSource");
DragManager.doDrag(img,ds,e,dragImg);
}
private function acceptDrag(e:DragEvent):void
{
var container:Canvas=e.currentTarget as Canvas;
DragManager.acceptDragDrop(container);
}
private function completeDrag(e:DragEvent):void
{
var dragTarget:Image=e.dragSource.dataForFormat("dragSource") as Image;
var img:Image=new Image();
img.source=dragTarget.source;
img.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent):void{Image(e.currentTarget).startDrag();});
img.addEventListener(MouseEvent.MOUSE_UP,function(e:MouseEvent):void{Image(e.currentTarget).stopDrag();});
var container:Canvas=e.currentTarget as Canvas;
container.addChild(img);
}
]]>
</mx:Script>
<mx:VBox x="56" y="61" width="520" height="435">
<mx:Canvas width="100%" height="40" x="20" y="50">
<mx:Image source="assets/test.gif" mouseDown="beginDrag(event)" width="23" height="19" x="10" y="11"/>
</mx:Canvas>
<mx:Canvas width="448" height="358" dragEnter="acceptDrag(event)" dragDrop="completeDrag(event)" borderColor="#39749D" borderStyle="solid" backgroundColor="#EDE5E5">
</mx:Canvas>
</mx:VBox>
</mx:Application>
首先,我們對需要拖動的物件增加mouseDown處理函式,本例中是對image物件進行拖動,mouseDown中首先獲取當前事件物件,然後建立一個副本,同時將該副本作為拖動源,通過DragManager開始拖動;對於接受拖動物件的容器dragEnter時通過DragManager.acceptDragDrop來指定該容器可接受拖動物件,最後在接受拖動物件容器的dragDrop事件處理函式中進行拖動完成的相關處理,本例中是向容器中增加圖形。
本文基於署名 2.5 中國大陸許可協議釋出,歡迎轉載,演繹或用於商業目的,但是必須保留本文的署名孫鏡濤(包含連結),具體操作方式可參考此處。如您有任何疑問或者授權方面的協商,請給我留言。