1. 程式人生 > >Flex拖動實現方法

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事件處理函式中進行拖動完成的相關處理,本例中是向容器中增加圖形。

Creative Commons License

本文基於署名 2.5 中國大陸許可協議釋出,歡迎轉載,演繹或用於商業目的,但是必須保留本文的署名孫鏡濤(包含連結),具體操作方式可參考此處。如您有任何疑問或者授權方面的協商,請給我留言