10.6.自定义列表类控件的拖动图像

10.6.1 问题
你希望在一个自定义列表类控件中进行拖拽操作时,自定义它的拖动图像。
10.6.2 解决办法
创建一个需要在拖拽操作时显示的UIComponent,并覆盖自定义列表类控件的dragImagegetter 方法。
10.6.3 讨论
Flex 框架中的列表类控件天生就会处理拖拽。这意味着你不需要为DragManager 发出的事件设置事件监听器。尽管如此,由于你不直接跟DragManager 打交道,所以当一个列表类控件中进行拖拽操作的时候,拖动图像默认是一个半透明的item renderer。你不能把拖动图像当作列表类控件的一个属性来设置,像在DragManager 的doDrag 方法中那样手动设置它。

要为一个列表类控件自定义拖动图像,你需要创建一个继承自该列表类控件的类,然后覆盖其受保护的dragImage getter 方法。覆盖该方法后,你可以返回你的自定义拖动图像。

下面的代码演示了如何创建一个继承自UIComponent 的拖动图像类,覆盖其受保护的createChildren 方法,在该方法中添加图像作为拖动时要显示的图像:
+展开
-ActionScript
package oreilly.cookbook {
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.UIComponent;
public class CustomDragProxy extends UIComponent {
public function CustomDragProxy() {super();}
override protected function createChildren():void {
super.createChildren();
var list:List = List( owner );
var items:Array = list.selectedIndices;
items.sort();
forvar i:int = 0; i < items.length; i++ ){
var item:Object = list.dataProvider[items[i]];
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler );
addChild( loader );
loader.load( new URLRequest( item.image ) );
var source:IListItemRenderer = list.indexToItemRenderer(items[i]);
loader.x = source.x;
loader.y = source.y - 20 + ( i * 45 );
}
}
private function completeHandler( evt:Event ):void {
var info:LoaderInfo = LoaderInfo( evt.target );
var image:Bitmap = Bitmap( info.content );
image.width = image.height = 40;
}
}
}

在对象内部,当其实例化的时候会调用受保护的createChildren 方法。在本例所覆盖的createChildren 方法中,你可以添加一些自定义对象到控件的显示列表中。我们假定把该控件用作拖动图像的控件为List 控件,所以owner 属性被转化为一个List 的实例。通过转换owner 属性,父List 实例里面的属性将可被本控件访问,用于修改它的显示列表。

Loader 的实例数量依赖与列表类控件中被选择的条目数量,它们被添加到显示列表中,根据与其相关联的条目中的图像URL 地址载入图像。图像载入后,一个item renderer 的实例通过该List 被访问了。使用indexToItemRenderer 方法定位父Loader 对象。

要为一个列表类控件自定义拖动图像,你需扩展这个控件并覆盖它的dragImage getter 方法。下面的代码演示了如何在dragImage getter 方法被调用时返回一个自定义的拖动图像:
+展开
-ActionScript
package oreilly.cookbook {
import mx.controls.List;
import mx.core.IUIComponent;
public class CustomList extends List {
public var dragProxy:Class;
public function CustomList() {super();}
override protected function get dragImage():IUIComponent {
if( dragProxy == null)return super.dragImage;
var proxy:IUIComponent = new dragProxy();
proxy.owner = this ;
return proxy
}
}
}

上述代码中,当dragImage getter 方法被调用,一个新的拖动图像被初始化并返回给调用者。如果你对之前的章节还有印象,你应该明白CustomDragProxy 可以通过owner 属性访问父列表的实例。在CustomList 中,dragImage getter 方法被覆盖了,它返回dragProxy 属性所声明的对象的一个实例。为CustomList 的dragProxy 属性设置一个拖拽代理的完整类名,可以让它在每次在dragImage 属性被访问的时候实例化。

下面的代码在应用程序中添加这个CustomList,并把它的dragProxy 属性设为CustomDragProxy:
+展开
-XML
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxmlxmlns:flexcookbook="oreilly.cookbook.*layout="horizontal"
creationComplete="creationHandler();">

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private function creationHandler():void {
contactList.dataProvider = new ArrayCollection([{label:'Josh', mage:'assets/bigshakey.png'
},{label:'Todd', image:'assets/smiley.png'}]);
}

]]>
</mx:Script>
<mx:Panel title="Contact List:width="200height="200">
<flexcookbook:CustomList id="contactListwidth="100%height="100%"
allowMultipleSelection="truedragEnabled="truedropEnabled="truedragMoveEnabled="true"
dragProxy="com.oreilly.flexcookbook.CustomDragProxy" />

</mx:Panel>
</mx:Application>

dataProvider 为自定义列表提供了一个数组,数组中每个元素包含一个label 属性和一个image 属性。列表的dragProxy 属性值在行内声明为CustomDragProxy 的完整类名。当一个拖动动作开始,一个CustomDragProxy 实例将被创建,然后载入所选列表条目中image 属性所指向的图片,并在拖拽操作时显示出来。

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


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