23.10.使用本地拖拽(Drag-and-Drop)API

23.10.1.问题
我想在应用程序内外拖动数据.
23.10.2.解决办法
添加数据到剪贴板,使用NativeDragManager类管理拖拽操作。
23.10.3.讨论
通过本地的drag-and-drop API文件系统和AIR应用程序之间可以进行数据传输。当一个拖拽姿势启动后,指定格式的数据被添加到剪贴板并传递给NativeDragManager的doDrag方法。

你可以注册事件监听器监听NativeDragManager类拖拽操作发出的completion事件。事件对象类型是NativeDragEvent类实例,通过NativeDragEvent.clipboard属性可访问剪贴板数据。

当用户用鼠标选择了应用程序的某一个元素,即一个拖拽姿势被启动。当用户按住鼠标,操作进入“拖阶段”,所有继承自flash.display.InteractiveObject类的注册组件都可接受拖拽动作。

当用户松开鼠标即表示拖拽姿势完成。启动拖拽姿势的组件被认为是“拖动源”,接受拽操作的InteractiveObject实例被认为是“拖拽目标”。

Flex Framework本身就支持应用程序内的拖拽操作,而本地的拖拽API运行在文件系统和AIR程序之间拖拽数据。我们推荐使用Flex FrameWork 拖拽API 。如果你熟悉mx.managers.DragManager 类在Flex 程序内传输数据的话, 那么你会发现flash.desktop.NativeDragManager类与此非常相似。有个重要方面需要注意的是两个类的DragSource对象被添加到DragManager实例中,而Clipboard对象被添加到NativeDragManager实例中。

下面的例子使用NativeDragManager添加一个图片到剪贴板,并使用拖拽姿势传输数据到文件系统的一个目录:
+展开
-XML
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="verticalwindowComplete="initHandler();closing="closeHandler();">

<mx:Script>
<![CDATA[
import mx.graphics.codec.PNGEncoder;
private var tempDir:File = File.createTempDirectory();
private var imageData:BitmapData;
private function initHandler():void {
imageData = new BitmapData( image.width, image.height );
imageData.draw( image );
}
private function closeHandler():void {
tempDir.deleteDirectory();
}
private function clickHandler():void {
var transfer:Clipboard = new Clipboard();
transfer.setData( ClipboardFormats.FILE_LIST_FORMAT, [getImageFile()], false);
NativeDragManager.dropAction = NativeDragActions.COPY;
NativeDragManager.doDrag(this ,transfer,imageData);
}
private function getImageFile():File {
var tempFile:File = tempDir.resolvePath( "img.png");
var png:ByteArray = new PNGEncoder().encode( imageData );
var stream:FileStream = new FileStream();
stream.open( tempFile, FileMode.WRITE );
stream.writeBytes( png );
stream.close();
return tempFile
}

]]>
</mx:Script>
<mx:Image id="imagesource="@Embed(source='assets/bigshakey.png')"
buttonMode="trueuseHandCursor="truemouseDown="clickHandler();" />

</mx:WindowedApplication>

当Image控件的mouseDown 事件触发时,clickHandler方法被调用,Clipboard对被创建。使用Clipboard.setData方法创建被移动的数据副本。Clipboard对象的数据格式是一个文件列表:里面只有一个图像文件,放置在文件系统的临时目录里。当用户拖动图片离开应用程序到文件系统的任何目录,松开鼠标按钮,图片文件便会被移动到目标位置。

你还可以拖动数据到另一个程序中。要让你的程序接受本地拖拽操作。需要监听NativeDragManager 类发出的拖拽动作事件。下面的例子是一个接受图片文件的应用程序:
+展开
-XML
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolutewindowComplete="initHandler();">

<mx:Script>
<![CDATA[
import mx.controls.Image;
private var loader:Loader;
private var xposition:Number;
private var yposition:Number;
private function initHandler():void {
addEventListener( NativeDragEvent.NATIVE_DRAG_ENTER,dragEnterHandler );
addEventListener( NativeDragEvent.NATIVE_DRAG_DROP,dragDropHandler );
}
private function dragEnterHandler( evt:NativeDragEvent ):void {
if( evt.clipboard.hasFormat( ClipboardFormats.FILE_LIST_FORMAT ) )
NativeDragManager.acceptDragDrop( this);
}
private function dragDropHandler( evt:NativeDragEvent ):void {
var pt:Point = globalToLocal(new Point( evt.localX, evt.localY ));
xposition = pt.x;
yposition = pt.y;
var files:Array = evt.clipboard.getData( ClipboardFormats.FILE_LIST_FORMAT ) as Array;
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler );
loader.load( new URLRequest( files[0].url ) );
}
private function completeHandler( evt:Event ):void {
var bmp:Bitmap = loader.content as Bitmap;
var image:Image = new Image();
image.source = bmp;
image.x = xposition;
image.y = yposition;
addChild( image );
}

]]>
</mx:Script>
</mx:WindowedApplication>

当应用程序初始化完成后,开始注册监听nativeDragEnterEvent和nativeDragDropEvent事件。

当一个文件被拖到程序上,调用NativeDragManager.acceptDragDrop方法。当dragDropEvent动作发生后,移动的数据被认为是一组文件对象,数组中的第一个文件被载入到Image控件。

虽然本节的例子演示了使用NativeDragManager 使AIR程序如何和文件系统交换数据,但是并不意味着只能是文件对象,你还可以交换位图数据和格式化字符串如HTML, URL, 或者是简单文本。

加支付宝好友偷能量挖...


评论(0)网络
阅读(120)喜欢(0)flash/flex/fcs/AIR