增加拖放功能
视觉开发环境典型地让您操作对象在应用程序中使用鼠标选择他们并在屏幕上四处移动。Flex拖放管理器让您选择一个对象,譬如List组件里的一个item(选项),或者是一个image(图片)组件,然后拖拽它到其他组件而添加到这个组件上。所有的Flex组件都支持拖放操作。Flex中的某些控件的附加功能也包括拖放操作,譬如List,Tree,和DataGrid。
拖放操作有三个主要阶段: 初始化, 扯拽, 释放。
初始化
用户创始拖放操作由使用鼠标选择一个导Flex组件或组件内的某一个选项(item),然后持续的按住鼠标移动组件或选项。例如,用户用鼠标选择List中的选项,当持续按着鼠标键,移动几个像素。被选择的组件称为drag initiator(拖拽创始者)。
拖拽
当持续按着鼠标键, 用户在Flex应用程序上移动鼠标时。Flex显示一个图象在拖拽的时候, 是drag proxy(拖拽代理器)。Drag source(拖拽来源)(DragSource 对象) 包含别拖拽的数据。
释放
当用户把drag proxy(拖拽代理器) 移动到在其它Flex组件, 那个组件成为一个可能的drop target(释放目标对象)。drop target(释放目标对象)能检查拖拽的来源的数据格式是否是目标所能接受的, 如果那样, 让用户把数据释放到组件上,如果释放目标对象的数据不是在一个可接受的格式, 释放目标对象可能禁止释放操作。
成功的释放操作, Flex添加数据到目标对象,在原始的位置删除它。
这个快速入门的提供几种方法在你的Flex的应用程序中实现拖拽操作。
这个快的开始描述实施拖放操作几个方式在您的Flex应用程序。
在List控件中使用拖放
几个Flex组件包括内置对拖放操作的支持。其中有DataGrid 、HorizontalList 、List、Menu、PrintDataGrid 、TileList, 和Tree 组件。
您可以生成drag initiators(拖拽创始者)并设置 dragEnabled
属性值为 true
。同样, 您能设置这些组件的释放对象的dropEnabled
属性
值为 true
。Flex让您通过拖拽移动选项从允许拖拽的组件到允许释放的组件, 或按下Ctrl通过拖拽来复制他们。
通过拖拽操作来复制选项
以下例子让您通过拖拽从List到另一个List复制选项。您能多次从drag initiator(拖拽创始者)到drop target(释放目标对象)拖拽来复制同样选项。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
width="365" height="225"
creationComplete="creationCompleteHandler();"
>
<mx:Script>
<![CDATA[
private function creationCompleteHandler():void
{
srclist.dataProvider = ['Reading', 'Skating', 'Movies'];
destlist.dataProvider = [];
}
]]>
</mx:Script>
<mx:Panel title="Select activities" layout="horizontal">
<mx:VBox width="50%">
<mx:Label text="Available activities"/>
<!-- Drag initiator -->
<mx:List
id="srclist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
/>
</mx:VBox>
<mx:VBox width="50%">
<mx:Label text="Activities I enjoy"/>
<!-- Drop target -->
<mx:List
id="destlist" width="100%" height="100"
dropEnabled="true"
/>
</mx:VBox>
</mx:Panel>
</mx:Application>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
width="365" height="225"
creationComplete="creationCompleteHandler();"
>
<mx:Script>
<![CDATA[
private function creationCompleteHandler():void
{
srclist.dataProvider = ['Reading', 'Skating', 'Movies'];
destlist.dataProvider = [];
}
]]>
</mx:Script>
<mx:Panel title="Select activities" layout="horizontal">
<mx:VBox width="50%">
<mx:Label text="Available activities"/>
<!-- Drag initiator -->
<mx:List
id="srclist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
/>
</mx:VBox>
<mx:VBox width="50%">
<mx:Label text="Activities I enjoy"/>
<!-- Drop target -->
<mx:List
id="destlist" width="100%" height="100"
dropEnabled="true"
/>
</mx:VBox>
</mx:Panel>
</mx:Application>
查看源代码,右击Flex应用程序(上面的flash影片)从弹出菜单中选取 View Source(察看代码)
使用拖放操作移动选项
属性dragMoveEnabled
的默认值为 false
, 只让您复制选项从List控件到其他的List。如果您修改上面的例子,在来源List组件增加 dragMoveEnabled
属性并设置为true
, 您能移动和复制元素, 如下所示。
默认动作是移动选项,复制选项, 持续按着鼠标在释放操作期间。
例子
<!-- Drag initiator -->
<mx:List
id="srclist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
dragMoveEnabled="true"
/>
查看源代码,右击Flex应用程序(上面的flash影片)从弹出菜单中选取 View Source(察看代码)
双向拖拽和释放功能
您将两个List均设置dragEnabled
属性和dropEnabled属性为true就能
允许双向拖拽和释放操作,如下:
例子
<!-- Both drag initiator and drop target -->
<mx:List
id="srclist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true"
/>
<!-- . . . -->
<!-- Both drag initiator and drop target -->
<mx:List
id="destlist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true"
/>
<mx:List
id="srclist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true"
/>
<!-- . . . -->
<!-- Both drag initiator and drop target -->
<mx:List
id="destlist" width="100%" height="100"
allowMultipleSelection="true"
dragEnabled="true"
dropEnabled="true"
dragMoveEnabled="true"
/>
查看源代码,右击Flex应用程序(上面的flash影片)从弹出菜单中选取 View Source(察看代码)
手动增加拖放操作功能
支持拖放操作在基于非List的组件和容器, 您必须明确地使用一系列的特别类和事件增加该功能。您使用DragManager 、DragSource, 和DragEvent 类来实现拖放操作。
Flex应用程序使用事件来控制拖放操作。
Drag initiator(拖拽创始者)事件
当您设置一个组件作为drag initiator(拖拽创始者), 您能使用 mouseDown
mouseMove
, 和 dragComplete
事件处理拖放操作。
mouseDown 和mouseMove 事件
当用户用鼠标选择组件并且持续按着鼠标键的时候mouseDown
事件被发送(dispatched)。 当鼠标移动的时候mouseMove
事件被发送(dispatched)。
以下例子插入四枚欧元硬币 ( 1 分 , 2 分, 5 的图象分, 和10 分) 并且使用image组件显示他们。在每个image组件, 您监听 mouseMove
事件和定义事件处理方法dragIt()
来处理这个事件。在 dragIt()
方法中, 你获得image对象的引用,那引用是由event对象的currentTarget属性产生的,并把这个引用存放到变量 dragInitiator中。
其次, 您创造一个 DragSource
对象和调用它的 addData()
方法存入 value
参数,传递到方法dragIt()
中去。您使用字符串 "value"
来
描述value参数的格式。您以后使用这串, 当创造您的释放目标对象, 检查是否允许选项释放到此。
由于您想要用户四处拖拽的时候显示硬币的图象, 您创造一个 Image
对象并设置它的来源和drag initiator(拖拽创始者)具有同样的硬币图象。您保存这个图象在一个局部变量叫 dragProxy
。
最后, 你调用静态doDrag()
方法在DragManager类和传递它的引用到drag initiator(拖拽创始者)、拖拽来源、事件对象, 和drag proxy(拖拽代理器)来开始拖拽操作。
您能四处拖拽硬币,但您无法释放它们到任何地方因为您未定义释放目标对象。以下部分描述怎么定义释放目标对象。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
viewSourceURL="src/DragAndDropDragInitiatorEvents/index.html"
width="500" height="160"
>
<mx:Script>
<![CDATA[
import mx.managers.DragManager;
import mx.core.DragSource;
// Embed the various Euro coin images. Images originally
// from Wikipedia (http://en.wikipedia.org/wiki/Euro_coins)
[Embed("assets/1c.png")]
[Bindable]
public var OneCent:Class;
[Embed("assets/2c.png")]
[Bindable]
public var TwoCents:Class;
[Embed("assets/5c.png")]
[Bindable]
public var FiveCents:Class;
[Embed("assets/10c.png")]
[Bindable]
public var TenCents:Class;
private function dragIt(event:MouseEvent, value:uint):void
{
// Get the drag initiator component from the event object.
var dragInitiator:Image = event.currentTarget as Image;
// Create a DragSource object.
var dragSource:DragSource = new DragSource();
// Add the data to the object.
dragSource.addData(value, 'value');
// Create a copy of the coin image to use as a drag proxy.
var dragProxy:Image = new Image();
dragProxy.source = event.currentTarget.source;
// Call the DragManager doDrag() method to start the drag.
DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
}
]]>
</mx:Script>
<mx:HBox>
<mx:Image
id="oneCent" source="{OneCent}"
mouseMove="dragIt(event, 1);"
/>
<mx:Image
id="twoCents" source="{TwoCents}"
mouseMove="dragIt(event, 2);"
/>
<mx:Image
id="fiveCents" source="{FiveCents}"
mouseMove="dragIt(event, 5);"
/>
<mx:Image
id="tenCents" source="{TenCents}"
mouseMove="dragIt(event, 10);"
/>
</mx:HBox>
</mx:Application>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
viewSourceURL="src/DragAndDropDragInitiatorEvents/index.html"
width="500" height="160"
>
<mx:Script>
<![CDATA[
import mx.managers.DragManager;
import mx.core.DragSource;
// Embed the various Euro coin images. Images originally
// from Wikipedia (http://en.wikipedia.org/wiki/Euro_coins)
[Embed("assets/1c.png")]
[Bindable]
public var OneCent:Class;
[Embed("assets/2c.png")]
[Bindable]
public var TwoCents:Class;
[Embed("assets/5c.png")]
[Bindable]
public var FiveCents:Class;
[Embed("assets/10c.png")]
[Bindable]
public var TenCents:Class;
private function dragIt(event:MouseEvent, value:uint):void
{
// Get the drag initiator component from the event object.
var dragInitiator:Image = event.currentTarget as Image;
// Create a DragSource object.
var dragSource:DragSource = new DragSource();
// Add the data to the object.
dragSource.addData(value, 'value');
// Create a copy of the coin image to use as a drag proxy.
var dragProxy:Image = new Image();
dragProxy.source = event.currentTarget.source;
// Call the DragManager doDrag() method to start the drag.
DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
}
]]>
</mx:Script>
<mx:HBox>
<mx:Image
id="oneCent" source="{OneCent}"
mouseMove="dragIt(event, 1);"
/>
<mx:Image
id="twoCents" source="{TwoCents}"
mouseMove="dragIt(event, 2);"
/>
<mx:Image
id="fiveCents" source="{FiveCents}"
mouseMove="dragIt(event, 5);"
/>
<mx:Image
id="tenCents" source="{TenCents}"
mouseMove="dragIt(event, 10);"
/>
</mx:HBox>
</mx:Application>
释放目标事件
释放目标对象可能使用各种各样的事件, 最重要是 dragEnter
dragDrop
, 和 dragExit
事件。
dragEnter
事件
dragEnter
事件被派遣(dispatch)当drag proxy(拖拽代理器) 从释放目标对象外面移动到释放对象的上面。组件必须在释放目标对象上定义一个事件监听器。在监听器上, 您能改变释放目标对象的外观,对用户提供视觉反馈,这组件能接受拖拽操作。例如, 您能画释放目标对象的边框, 并把焦点移动到释放目标对象。
dragExit
事件
dragExit
事件被派遣(dispatch)当用户拖拽到释放目标对象的外面时, 但不释放数据到目标对象上。如果您修改了它的外观以响应dragEnter 事件或其它事件,您能使用这个事件恢复释放目标对象到它的正常外观。
dragDrop
事件
dragDrop
事件被派遣(dispatch)当用户在释放目标对象上释放鼠标时。您能使用这个事件监听器把拖拽数据添加到释放目标对象上。
在以下例子您创造一个箱子容器作为释放目标和定义事件管理类(handlers)来监听dragEnter 、dragExit 和dragDrop 事件。在箱子容器里有Lable组件, 用这个组件显示投到箱子里硬币的总值。
在dragEnter
事件管理里, 检查拖拽来源包含 "value"
格式。只有包含这个格式的对象(即, 硬币在这个例子) 才能投在释放目标对象上。如果释放了, 对用户的视觉表现为, 在投入一个选项到箱子时增加箱子容器的边框的厚度。您将通知DragManager, 箱子容器将调用它的 acceptDragDrop()
方法接受drag initiator(拖拽创始者)。
dragExit
事件的事件管理者, 您恢复箱子容器的视觉外观象征 drag proxy(拖拽代理器)不再存在。
终于, dragDrop
事件的事件管理者, 它将被调用在用户投下一枚硬币到释放目标对象之后,计数器totalValue
的值加上投到箱子硬币的值并且恢复箱子容器外观, 释放操作就完成了。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
width="525" height="270"
viewSourceURL="src/DragAndDropDragDropTargetEvents/index.html"
>
<mx:Script>
<![CDATA[
import mx.events.DragEvent;
import mx.containers.Box;
import mx.managers.DragManager;
import mx.core.DragSource;
// Embed the various Euro coin images. Images originally
// from Wikipedia (http://en.wikipedia.org/wiki/Euro_coins)
[Embed("assets/1c.png")]
[Bindable]
public var OneCent:Class;
[Embed("assets/2c.png")]
[Bindable]
public var TwoCents:Class;
[Embed("assets/5c.png")]
[Bindable]
public var FiveCents:Class;
[Embed("assets/10c.png")]
[Bindable]
public var TenCents:Class;
[Bindable]
private var totalValue:uint;
private function dragIt(event:MouseEvent, value:uint):void
{
// Get the drag initiator component from the event object.
var dragInitiator:Image = event.currentTarget as Image;
// Create a DragSource object.
var dragSource:DragSource = new DragSource();
// Add the data to the object.
dragSource.addData(value, 'value');
// Create a copy of the coin image to use as a drag proxy.
var dragProxy:Image = new Image();
dragProxy.source = event.currentTarget.source;
// Call the DragManager doDrag() method to start the drag.
DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
}
// Called if the user drags a drag proxy onto the drop target.
private function dragEnterHandler(event:DragEvent):void
{
// Get the drop target component from the event object.
var dropTarget:Box=event.currentTarget as Box;
// Accept the drag only if the user is dragging data
// identified by the 'value' format value.
if (event.dragSource.hasFormat('value'))
{
// Make the border of the Box thicker to
// visually signal to the user that they can
// drop the coin there.
dropTarget.setStyle("borderThickness", 5);
// Accept the drop.
DragManager.acceptDragDrop(dropTarget);
}
}
// Called if the user drags the drag proxy away from the drop target.
private function dragExitHandler(event:DragEvent):void
{
// Get the drop target component from the event object.
var dropTarget:Box=event.currentTarget as Box;
// Set the border of the Box to its default value
// to visually indicate that the user is no longer
// over the drop target.
revertBoxBorder();
}
// Called if the target accepts the dragged object and the user
// releases the mouse button while over the drop target.
private function dragDropHandler(event:DragEvent):void
{
// Get the data identified by the color format from the drag source.
var value:uint = event.dragSource.dataForFormat('value') as uint;
// Add the value to the total
totalValue += value;
// Set the border of the Box to its default value
revertBoxBorder();
}
// Helper method to revert the Box's border to a 1 pixel outline.
private function revertBoxBorder():void
{
amountDisplay.setStyle("borderThickness", 1);
}
]]>
</mx:Script>
<mx:HBox>
<mx:Image
id="oneCent" source="{OneCent}"
mouseMove="dragIt(event, 1);"
/>
<mx:Image
id="twoCents" source="{TwoCents}"
mouseMove="dragIt(event, 2);"
/>
<mx:Image
id="fiveCents" source="{FiveCents}"
mouseMove="dragIt(event, 5);"
/>
<mx:Image
id="tenCents" source="{TenCents}"
mouseMove="dragIt(event, 10);"
/>
</mx:HBox>
<mx:Box
id="amountDisplay"
borderStyle="solid" borderColor="#000000" backgroundColor="#FFFFFF"
width="100%" height="100" horizontalAlign="center" verticalAlign="middle"
dragEnter="dragEnterHandler(event);"
dragExit="dragExitHandler(event);"
dragDrop="dragDropHandler(event);"
>
<mx:Label text="{totalValue + ' pence'}" fontSize="48"/>
</mx:Box>
</mx:Application>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
width="525" height="270"
viewSourceURL="src/DragAndDropDragDropTargetEvents/index.html"
>
<mx:Script>
<![CDATA[
import mx.events.DragEvent;
import mx.containers.Box;
import mx.managers.DragManager;
import mx.core.DragSource;
// Embed the various Euro coin images. Images originally
// from Wikipedia (http://en.wikipedia.org/wiki/Euro_coins)
[Embed("assets/1c.png")]
[Bindable]
public var OneCent:Class;
[Embed("assets/2c.png")]
[Bindable]
public var TwoCents:Class;
[Embed("assets/5c.png")]
[Bindable]
public var FiveCents:Class;
[Embed("assets/10c.png")]
[Bindable]
public var TenCents:Class;
[Bindable]
private var totalValue:uint;
private function dragIt(event:MouseEvent, value:uint):void
{
// Get the drag initiator component from the event object.
var dragInitiator:Image = event.currentTarget as Image;
// Create a DragSource object.
var dragSource:DragSource = new DragSource();
// Add the data to the object.
dragSource.addData(value, 'value');
// Create a copy of the coin image to use as a drag proxy.
var dragProxy:Image = new Image();
dragProxy.source = event.currentTarget.source;
// Call the DragManager doDrag() method to start the drag.
DragManager.doDrag(dragInitiator, dragSource, event, dragProxy);
}
// Called if the user drags a drag proxy onto the drop target.
private function dragEnterHandler(event:DragEvent):void
{
// Get the drop target component from the event object.
var dropTarget:Box=event.currentTarget as Box;
// Accept the drag only if the user is dragging data
// identified by the 'value' format value.
if (event.dragSource.hasFormat('value'))
{
// Make the border of the Box thicker to
// visually signal to the user that they can
// drop the coin there.
dropTarget.setStyle("borderThickness", 5);
// Accept the drop.
DragManager.acceptDragDrop(dropTarget);
}
}
// Called if the user drags the drag proxy away from the drop target.
private function dragExitHandler(event:DragEvent):void
{
// Get the drop target component from the event object.
var dropTarget:Box=event.currentTarget as Box;
// Set the border of the Box to its default value
// to visually indicate that the user is no longer
// over the drop target.
revertBoxBorder();
}
// Called if the target accepts the dragged object and the user
// releases the mouse button while over the drop target.
private function dragDropHandler(event:DragEvent):void
{
// Get the data identified by the color format from the drag source.
var value:uint = event.dragSource.dataForFormat('value') as uint;
// Add the value to the total
totalValue += value;
// Set the border of the Box to its default value
revertBoxBorder();
}
// Helper method to revert the Box's border to a 1 pixel outline.
private function revertBoxBorder():void
{
amountDisplay.setStyle("borderThickness", 1);
}
]]>
</mx:Script>
<mx:HBox>
<mx:Image
id="oneCent" source="{OneCent}"
mouseMove="dragIt(event, 1);"
/>
<mx:Image
id="twoCents" source="{TwoCents}"
mouseMove="dragIt(event, 2);"
/>
<mx:Image
id="fiveCents" source="{FiveCents}"
mouseMove="dragIt(event, 5);"
/>
<mx:Image
id="tenCents" source="{TenCents}"
mouseMove="dragIt(event, 10);"
/>
</mx:HBox>
<mx:Box
id="amountDisplay"
borderStyle="solid" borderColor="#000000" backgroundColor="#FFFFFF"
width="100%" height="100" horizontalAlign="center" verticalAlign="middle"
dragEnter="dragEnterHandler(event);"
dragExit="dragExitHandler(event);"
dragDrop="dragDropHandler(event);"
>
<mx:Label text="{totalValue + ' pence'}" fontSize="48"/>
</mx:Box>
</mx:Application>
查看源代码,右击Flex应用程序(上面的flash影片)从弹出菜单中选取 View Source(察看代码)