Flex 拖动详解

Flex中有一些控件内置了对drag-and-drop操作的支持,实现也相对方便,但往往要完成这样的操作,将一幅图片(没有内置drag-and-drop操作)拖动到一个表格中,在表格中显示相关信息,该如何实现呢?答案很简单,你必须显式的通过一系列专门的类和事件来添加对drag-and-drop的支持。

以下是实现drag-and-drop操作所用到的类和事件,

drag-and-drop 类:

功能
DragManager 管理 drag-and-drop 操作;例如,它的 doDrag() 方法启动一个拖拽操作。
DragSource 确定并且储存那些被拖拽的数据。它也提供一些附加的拖拽管理功能,例如可以在需要数据时添加侦听器的功能。
DragEvent 响应 drag-and-drop 事件,例如当用户将对象拖拽到一个拖拽目标上时。

drag-and-drop 事件:

事件 描述
mouseDown   and
mouseMove
mouseDown 事件是当用户通过按住鼠标键来选择一个控件时广播。mouseMove 事件是当鼠标移动时广播。对于大多数控件,你初始化 drag-and-drop 操作时是通过这两个事件。对于像 Tree 和 Grid 这些含有 dragEnabled 属性的控件,它本身提供了内在的初始化拖拽操作的支持,你不需要使用鼠标事件。
dragComplete 在一个拖拽操作完成时广播,无论当拖拽数据释放到一个释放目标,还是当 drag-and-drop 操作结束并没有进行释放操作。你可以使用这个事件来进行任意最终的 drag-and-drop 操作清理工作。例如,如果一个用户从一个列表拖拽一个List控件数据项到另一个列表,你可以使用这个侦听器来删除源List控件中的数据项。
释放目标可以使用以下的事件:
dragEnter 当一个拖拽代理从目标外移动到目标上时广播。一个组件成为一个释放目标必须为这个事件定义一个侦听器。使用侦听器,你可以改变释放目标的外观提供一个可视化的效果以便用户了解到这个组件可以接 受拖拽操作,例如,你可以在释放目标周围绘制一个边框,或者使释放目标获得焦点。
dragDropdragDrop 当鼠标在目标上释放时广播。你可以使用这个事件添加拖拽数据到目标上。

drag-and-drop 过程:

  • 一个组件通过以下方法中的一种成为一个 drag-and-drop 初始器:

拥有 dragEnabled 属性的组件(这些组件包括 List,Tree,DataGrid,PrintDataGrid Menu,HorizontalList 以及 TileList):如果 dragEnabled 属性设置为 true,当用户此组件点击移动鼠标时,Flex 自动将其转为初始器。

没有 dragEnabled 属性的组件:对于其他所有的组件,必须接收到用户启动一个拖拽操作的趋 势,然后显式的成为一个初始器。代表性地,你使用 mouseMove 或者 mouseDown 事件来启动 drag-and-drop 操作。


    • 组件创建一个 mx.core.DragSource 类的实例,其中包含要拖拽的数据,并且指定数据的格式。
    • 组件调用 mx.managers.DragManager.doDrag() 方法,来初始化 drag-and-drop 操作。
  • 当鼠标键一直按住时,用户在程序内部移动鼠标。Flex 在程序中显示拖拽代理图像。
注意 当拖拽代理没有在一个释放目标上时释放鼠标将结束 drag-and-drop 操作。Flex 会产生一个 DragComplete 事件于拖拽初始器,并且 DragManager.getFeedback() 方法返回 DragManager.NONE.

  • 如果用户移动拖拽代理到一个 Flex 组件之上,Flex 广播一个 dragEnter 事件到这个准释放目标。这个目标组件必须为 dragEnter 事件定义一个事件侦听器,这样才能成为一个释放目标。

dragEnter 事件侦听器将检查 DragSource 对象以便决定拖拽数据是否是可接受的格式。为了接受释放,事件侦听器调用 DragManager.acceptDragDrop() 方法

    • 如果释放目标拒绝释放,释放目标组件的父级链中组件将逐一被检查,来检测是否有可以接受释放数据的组件。
    • 如果释放目标或者其父组件中的一个组件可以接受释放,当用户在目标上移动代理时,Flex 广播一个 dragOver 事件。
  • 可选地,目标对象可以对 dragOver 事件进行处理。例如,目标可以使用这个事件侦听器来使其自身获得焦点。
  • 如果用户放弃在释放目标上释放数据,并且一直没有松开鼠标将拖拽代理移动到释放目标之外,Flex 广播一个 dragExit 事件。释放目标可以处理这个事件,例如去回滚任何在 dragOver 事件侦听器中进行的操作。
  • 如故用户在释放目标上松开鼠标,Flex 广播一个 dragDrop 事件。释放目标的 dragDrop 事件侦听器添加拖拽数据到目标中。
  • 如果拖拽操作完成,Flex 广播一个 dragComplete 事件。拖拽初始器可以处理这个事件,例如删除从数据提供器(data provider)中删除拖拽数据。
实例描述:

控件A拖动到控件 B上,然后改变各自的位置。

1.ControlA.mxml

 

1 <?xml version="1.0" encoding="utf-8"?>

2 < mx:Canvas backgroundColor = " #000000 " mouseDown = " startMove(event) " mouseUp = " stopMove(event) " xmlns:mx = " http://www.adobe.com/2006/mxml " width = " 400 " height = " 300 " >
3 < mx:Script >
4     <! [CDATA[
5         import mx.core.DragSource;
6         import mx.managers.DragManager;
7          /* ***************************************************************************
8          * 控件A
9          * 用于拖动,捕获mouseDown 和 mouseUp事件,触发拖动
10         *************************************************************************** */
11        
12         /* *
13          * 鼠标按下事件处理方法
14          */
15         private function startMove(event:Event): void  
16         { 
17             // Sprite 类的startDrag方法来触发拖动
18             Sprite(event.target).startDrag(); 
19            
20             // 其他控件感知拖动事件,需要用DragManager的doDrag 方法触发
21             var obj:DragSource = new DragSource();
22             // Data 包含,拖动时该控件的x,y 信息
23             var location:String = this .x + " , " + this .y;
24             obj.addData(location, " LocationFormat " );
25             var mouseEvent:MouseEvent = new MouseEvent(MouseEvent.MOUSE_DOWN);
26             DragManager.doDrag( this ,obj,mouseEvent);
27         } 
28         /* *
29         * 鼠标弹起事件处理方法
30         */
31         private function stopMove(event:Event): void  
32         { 
33             // Sprite 类的stopDrag 方法来触发停止拖动
34             Sprite(event.target).stopDrag(); 
35         } 
36        
37        
38     ]] >
39 < / mx:Script>
40     < mx:Button x = " 48.5 " y = " 38 " label = " A " width = " 161 " height = " 89 " fontSize = " 28 "/ >
41    
42 < / mx:Canvas>
43

2.ControlB.mxml

1 <?xml version="1.0" encoding="utf-8"?>

2 < mx:Canvas backgroundColor = " #000000 " dragOver = " dragOverHandler(event) " dragDrop = " doDragDropHandler(event) " dragEnter = " doDragEnterHandler(event) " xmlns:mx = " http://www.adobe.com/2006/mxml " width = " 400 " height = " 300 " >
3 < mx:Script >
4     <! [CDATA[
5         import mx.core.UIComponent;
6         import mx.managers.DragManager;
7         import mx.events.DragEvent;
8          /* ***************************************************************************
9          * 控件B
10          * 处理dragOver,dragDrop,dragEnter事件
11         *************************************************************************** */
12         /* *
13          * dragOver 事件处理
14          */
15         public function dragOverHandler(event:DragEvent): void
16         {
17              if (event.ctrlKey)
18                 DragManager.showFeedback(DragManager.COPY);
19             else if (event.shiftKey)
20                 DragManager.showFeedback(DragManager.LINK);
21             else
22                 DragManager.showFeedback(DragManager.MOVE);
23         }
24        
25         /* *
26          * dragEnter 事件,主要是,要接收一些拖动到其上的控件,特定的控件,不然所有的控件都可以拖动到其上。
27          */
28         public function doDragEnterHandler(event:DragEvent): void
29         {
30             var dropTarget:UIComponent = event.currentTarget as UIComponent;
31             if (event.dragSource.hasFormat( ' LocationFormat ' ))
32             {
33                 DragManager.acceptDragDrop(dropTarget);
34                }
35         }
36        
37         /* *
38          * 在此处得知拖动过来的控件,以及一些信息
39          */
40         public function doDragDropHandler(event:DragEvent): void
41         {
42             var dragObj:String = event.dragSource.dataForFormat( " LocationFormat " ).toString();
43             var locationArray:Array = dragObj.split( " , " );
44             var x:Number = Number(locationArray[ 0 ]);
45             var y:Number = Number(locationArray[ 1 ]);
46             this .x = x;
47             this .y = y;
48             event.preventDefault();
49
50         }
51     ]] >
52 < / mx:Script>
53     < mx:Button x = " 35.5 " y = " 36 " label = " B " width = " 161 " height = " 89 " fontSize = " 28 "/ >
54    
55 < / mx:Canvas>
56

3.主界面:TestDragOver.mxml

1 <?xml version="1.0" encoding="utf-8"?>

2 < mx:WindowedApplication xmlns:mx = " http://www.adobe.com/2006/mxml " layout = " absolute " xmlns:local = " * " >
3 < local:ControlA width = " 250 " height = " 250 " x = " 39 " y = " 10 " >
4    
5 < / local:ControlA>
6 < local:ControlB x = " 344 " y = " 10 " width = " 250 " height = " 250 " >
7    
8 < / local:ControlB>
9 < / mx:WindowedApplication>
10

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值