将air中的文件(数据)拖拽到操作系统。想将文件从air中拖出,就用到文件承诺。
文件承诺是指,当您希望用户能拖放还不存在或位于其他位置(不在您的本地机器上)的文件时,您放在剪贴板上的内容。例如,远程服务器上的文件,或是您只希望在用户尝试拖放它们时生成的文件(如 CSV 文件)。文件承诺并不是实际存在的文件;正如其名,它表示在用户选择放下位置后,在之后的某个时刻提供文件的承诺。
在AIR中,并没有一个直接的文件承诺类,而是提供了一个IFilePromise的接口。就是说,只要实现这个接口的类,就具备了文件承诺的功能。这对于初学者有些不便,不像File类那样直接就可以使用,不过这也提供了更大的扩展性。你可以为你的各种数据实现文件承诺功能。虽然没有具体的文件承诺类,AIR也有一个类实现了IFilePromise的接口。就是 URLFilePromise类。
var cb:Clipboard = new Clipboard(); var items:Array = fileData.selectedItems; var promises:Array = new Array(); for each (var item:Object in items)
{ var fp:URLFilePromise = new URLFilePromise(); var req:URLRequest = new URLRequest(item.url); fp.request = req; fp.relativePath = item.name; promises.push(fp); } cb.setData(ClipboardFormats.FILE_PROMISE_LIST_FORMAT, promises); NativeDragManager.doDrag(fileData, cb);
以下是使用文件承诺时需要记住的几点:
文件承诺只适用于拖放操作(不适用于复制和粘贴)。不能将文件承诺放在普通剪贴板上供最终用户粘贴。(实际上,您可以这样操作,但 setData 将返回 false,表明这样操作无效。)
只能在 AIR 应用程序与本机文件系统之间使用文件承诺。不能使用文件承诺在 AIR 或本机应用程序之间拖放或复制和粘贴。
如果文件承诺由于任何原因失败,将从文件系统中自动删除不完整的文件,这样您的代码不必进行清理操作。不会删除之前下载的文件,并且仍将尝试后续下载。
从air中拖出的对象,用的比较多的就是位图。那么,我们就自定义一个位图的承诺类,让它实现IFilePromise接口。
package { import flash.desktop.IFilePromise; import flash.display.BitmapData; import flash.display.JPEGEncoderOptions; import flash.events.ErrorEvent; import flash.utils.ByteArray; import flash.utils.IDataInput; /** * * @author vini123 * 实现了IFilePromise接口,是将air中的文件拖入到桌面的前提之一 */ public class BitmapFilePromise implements IFilePromise { private var bitmapData:BitmapData; private var dataPath:String; /** * * @param data 数据 * @param path 文件名 * */ public function BitmapFilePromise(data:BitmapData , path:String) { bitmapData = data; dataPath = path; } public function get relativePath():String { return dataPath; } public function get isAsync():Boolean { return false; } public function open():IDataInput { var byteArray:ByteArray = new ByteArray(); var jpgEncoder:JPEGEncoderOptions = new JPEGEncoderOptions(); bitmapData.encode(bitmapData.rect , jpgEncoder , byteArray); byteArray.position = 0;; return byteArray; } public function close():void { } public function reportError(e:ErrorEvent):void { } } }
拖拽是通过鼠标事件MOUSE_DOWN来触发,通过NativeDragManager.doDrag启动的。这个过程中,先需要创建剪贴板Clipboard,然后向剪贴板中插入数据,插入的数据对应着类型:ClipboardFormats.FILE_PROMISE_LIST_FORMAT,数据是一个包含实现了IFilePromise的数组。
完整代码:
package { import flash.desktop.Clipboard; import flash.desktop.ClipboardFormats; import flash.desktop.NativeDragManager; import flash.display.Bitmap; import flash.display.Loader; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.net.URLRequest; [SWF(width = "720" , height = "450" , frameRate="30")] public class DragFileToOs extends Sprite { private var textArea:TextArea; private var bitmap:Bitmap; private var container:Sprite; public function DragFileToOs() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.addEventListener(Event.RESIZE , resizeHandler); initialize(); } private function initialize():void { textArea = new TextArea("微软雅黑" , 12 , 0xff0000 , stage.stageWidth - 16 , stage.stageHeight - 16 ); addChild(textArea); textArea.x = textArea.y = 8; loadFile(); } private function loadFile():void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE , completeHandler); loader.load(new URLRequest("http://img.zcool.cn/community/01be3a554344dc0000002b01013da7.jpg")); } private function completeHandler(e:Event):void { bitmap = e.target.content as Bitmap; if(!container) { container = new Sprite(); addChild(container); } container.addChild(bitmap); resizeBitmap(); container.addEventListener(MouseEvent.MOUSE_DOWN , mouseDownHandler); } private function mouseDownHandler(e:MouseEvent):void { var bitmapFilePromise:BitmapFilePromise = new BitmapFilePromise(bitmap.bitmapData , "vini.jpg"); var clipBoard:Clipboard = new Clipboard(); clipBoard.setData(ClipboardFormats.FILE_PROMISE_LIST_FORMAT , [bitmapFilePromise]); NativeDragManager.doDrag(container , clipBoard, bitmap.bitmapData , new Point(-bitmap.width * 0.5 , -bitmap.height * 0.5)); } private function resizeHandler(e:Event):void { if(textArea) { textArea.x = stage.stageWidth * 0.5 - textArea.width * 0.5; textArea.y = stage.stageHeight * 0.5 - textArea.height * 0.5; } resizeBitmapPos(); } private function resizeBitmapPos():void { if(container) { container.x = stage.stageWidth * 0.5 - container.width * 0.5; container.y = stage.stageHeight * 0.5 - container.height * 0.5; } } private function resizeBitmap():void { if(container) { if(container.width/container.height > (textArea.width - 3)/(textArea.height - 3)) { container.width = textArea.width - 3; container.scaleY = container.scaleX; } else { container.height = textArea.height - 3; container.scaleX = container.scaleY; } resizeBitmapPos(); } } } } import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; class TextArea extends Sprite { private var textField:TextField; private var textWidth:int; private var textHeight:int; private const PADDING:int = 8; public function TextArea(font:String , size:int , color:int , tw:int , th:int , bold:Boolean = false) { textField = new TextField(); textField.autoSize = TextFieldAutoSize.LEFT; textField.defaultTextFormat = new TextFormat(font , size , color , bold); textField.wordWrap = true; textField.multiline = true; textField.width = tw - PADDING * 2; textField.height = th - PADDING * 2; addChild(textField); textField.x = PADDING; textField.y = PADDING; textWidth = tw; textHeight = th; mouseChildren = false; mouseEnabled = false; graphics.clear(); graphics.lineStyle(2 , color ); graphics.beginFill(color , 0); graphics.drawRect(0 , 0 , tw , th); graphics.endFill(); } public function set text(value:String):void { textField.appendText(value + "\n"); if(textField.height > (height - PADDING * 2)) { textField.text = value; } } override public function get width():Number { return textWidth; } override public function get height():Number { return textHeight; } }
参考网站:http://www.adobe.com/cn/devnet/air/flex/articles/using_file_promises.html