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事件处理函数中进行拖动完成的相关处理,本例中是向容器中增加图形。

原文出自:http://www.cnblogs.com/jingtao/archive/2010/08/10/1796155.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值