应用程序跟操作系统(包裹操作系统里的应用程序)之间的文件拖拽,是一种很常见的操作行为。AIR也是。AIR拖拽,除了这一操作行为,还有其他的。这里就总结下。

AIR拖拽的分类:
1,从操作系统(包裹操作系统里的应用程序)拖拽文件到AIR.
2,从AIR拖拽文件到操作系统。
3,AIR内部之间文件的拖拽。

无论怎么拖,勾托抹托,上拖下拖,左拖右拖。都离不开一个东东,那就是剪贴板。就是Clipboard。在拖拽与接收之间,先得有个剪贴板。想取得剪贴板,可以用ClipBoard的静态属性generalClipboard获取。

var clipboard:Clipboard = Clipboard.generalClipboard;


但NativeDragEvent的clipboard(事件接受过来的)和Clipboard.generalClipboard会有不同(昨天测试发现的,还待继续验证)。也许,通过ctrl+c和ctrl+v的时候,Clipboard.generalClipboard会有大的用途(也待测试)。

上边的两种方式,是直接获取Clipboard。我们还可以自己创建一个Clipboard。这种情况,会应用在将文件拖到操作系统或air之间的拖拽。

var clipboard:Clipboard = new Clipboard();

1-写入数据。
通过setData方法可以将数据写入Clipboard。

public function setData(format:String, data:Object, serializable:Boolean = true):Boolean

data的参数必须是适用于指定格式的相应数据类型,有以下其中:

    ClipboardFormats.BITMAP_FORMAT 指定剪贴板上的图像数据
    ClipboardFormats.FILE_LIST_FORMAT 指定剪贴板上存储一个或多个文件(File的实例,放在一个数组中。)。【可以是文件(如.txt,.jpg,.xls等)也可以是文件夹】
    ClipboardFormats.FILE_PROMISE_LIST_FORMAT //承诺实施(将文件拖动到操作系统)
    ClipboardFormats.HTML_FORMAT 指定剪贴板上存储HTML格式的文本。
    ClipboardFormats.RICH_TEXT_FORMAT 包含 RTF 格式数据的 ByteArray
    ClipboardFormats.TEXT_FORMAT 指定剪贴板上存储无格式的纯文本
    ClipboardFormats.URL_FORMAT 指定剪贴板上存储一个或多个文件(采用URL形式)。这个数据作为AS字符串传递,而不作为File类的实例。URL之间的分隔符(如果有多个)是一个换行加回车符。(\r\n)

其实,还可以自定义格式。不过这种自定义格式只能用在air内部的拖拽。定制格式命名不要以flash:或air:开头。
除了通过setData方法写入数据,还可以通过setDataHandler方法写入数据。可以延迟呈现某一格式的数据。

public function setDataHandler(format:String, handler:Function, serializable:Boolean = true):Boolean

注意:
1,两种写入方式的最好一个参数,serializable。当值为false的时候,只使用对象的引用可用。true引用和值都可用。
2,如果同时使用 setData() 和 setDataHandler() 方法添加具有相同格式名称的数据表示方式,则永远也不会调用该处理函数。

2-剪贴板的传输模式

public function getData(format:String, transferMode:String = "originalPreferred"):Object

从剪贴板粘贴数据时,可以按值或按引用粘贴。(getData时,默认值是ClipboardTransferMode.ORIGINAL_PREFERRED)
ClipboardTransferMode.CLONE_ONLY 只粘贴副本(按值传递)如果系统无法粘贴副本,则在相应位置粘贴一个null值。
ClipboardTransferMode.CLONE_PREFERRED 尝试粘贴副本。如果系统无法创建副本,则在相应的位置粘贴引用。
ClipboardTransferMode.ORIGINAL_ONLY 只粘贴引用。如果系统无法粘贴引用,则在相应位置粘贴一个null。
ClipboardTransferMode.ORIGINAL_PREFERRED 尝试粘贴引用。如果系统无法创建引用,则在相应位置粘贴副本。

3-数据串行化
要让AIR运行时环境粘贴一个副本而不是对象的一个引用,数据必须是可串行化的(serializable)。串行化(Serialization)是指类能够被复制。事实上,串行化就是将类的属性转换为ByteArray的过程。按值粘贴对象时,将把包含类所有属性的ByteArray复制到类的一个新实例中。以这种方式粘贴副本的过程称为逆串行化(deserialization)。

很多内置Flash和Flex类本身就是可串行化的,包括所有基本数据类型(如int、String、Array等),以及所有实现了IExternalizable接口的类。

实际上,一些既不是基本类型也没有实现IExternalizable接口的类也可以串行化。对于这些类,只会为类的公共变量建立副本,而所有内部、保护或私有成员则被忽略。

看起来,要考虑的问题好像很麻烦。不过只需记住,要把你自己定制类的实例复制到剪贴板,而且要求粘贴公共属性及其他成员,只有在这种情况下才需要定制类显式地实现IExterna- lizable接口。对于常规操作,比如从DataGrid的dataProvider复制字符串的ArrayCollection,则没有必要实现这个接口。

IExternalizable接口要求实现此接口的类必须包含两个方法:readExternal()和writeEx- ternal()。以下是一个简单的可串行化类的基本骨架。

注意,这个例子中writeExternal()方法接受一个名为output的参数,这是一个实现了IDataOutput的对象。实际上,将由这个参数完成串行化过程。output参数具体采用所需的特定数据类型将数据写至ByteArray。下面这个例子显示了两种不同的数据类型–一个是字符串,另一个是无符号整数。

需要串行化这个对象时,AIR框架会隐式地调用writeExternal(),并传入一个ByteArray,数据将写至这个ByteArray。ByteArray类实现了IDataOutput。对数据逆串行化时,会隐式地调用这个类的readExternal()方法,并传入已经填充的ByteArray。

要注意重要的一点,串行化的顺序必须与逆串行化的顺序完全一致。由于数据存储在一个ByteArray中,因此,增加到数组的第一个元素必须是从数组中读取的第一个元素。所以,在前面的例子中,如果readExternal()中设置元素的顺序与writeExternal()中写数据的顺序不一致,这个过程就会失败。

如果要控制类的串行化过程并为类注册一个别名,那么还需要使用flash.net.register- ClassAlias方法另外多加一步。这一步允许随数据将类信息写入ByteArray。如果忽略这一步,数据的逆串行化副本则是Object类的一个通用实例,而不是你所复制的那个特定类的实例。通常情况下,会从构造函数调用registerClassAlias方法,以下是一个可串行化类的完整例子。

在getData的时候,可以对Clipboard所包含的传递的数据类型进行检测,看是否是你需要的。在事件NATIVE_DRAG_ENTER时,也可以检测是否是包含所需要的数据,然后是否去接受数据。检测我们用clipboard的hasFormat方法,参数是上边那指定的七种对应格式类型。当然air内部之间可以自定义对应数据类型。

参考网站:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/desktop/Clipboard.html

http://book.51cto.com/art/200906/130945.htm

http://help.adobe.com/en_US/air/reference/html/flash/desktop/ClipboardFormats.html