Flex4 - 自定义组件增加拖放行为
作者:hangge | 2014-12-12 16:07
Flex自带的List等组件默认就有拖放行为。而对于自定义的组件,通过DragManager也可以添加拖放行为。


--- 产品类 ProductItem.as ---
--- 产品皮肤 ProductItemSkin.mxml ---
--- 购物车类 ShoppingCart.as ---
--- 购物车皮肤 ShoppingCartSkin.mxml ---
下面是一个购物车的demo:
(1)点击产品即可拖动,同时拖动代理是产品的快照,而不是默认方框
(2)购物车判断并接收产品(产品移入购物车有模糊效果,表示可以接收)
(3)产品和购物车都使用了皮肤Skin
效果图:

代码结构:

代码如下:
--- 主应用 CustomDragWithCart.mxml ---
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:components="components.*"
fontFamily="微软雅黑">
<s:layout>
<s:HorizontalLayout paddingLeft="20" paddingTop="20" />
</s:layout>
<s:VGroup width="100">
<s:Label text="货架" fontWeight="bold" fontSize="14"
paddingTop="5"/>
<components:ProductItem title="产品1" color="0x333333"
skinClass="assets.skins.ProductItemSkin" />
<components:ProductItem title="产品2" color="0xFF6666"
skinClass="assets.skins.ProductItemSkin" />
<components:ProductItem title="产品3" color="0x66FF66"
skinClass="assets.skins.ProductItemSkin" />
</s:VGroup>
<components:ShoppingCart title="购物车" minHeight="200"
skinClass="assets.skins.ShoppingCartSkin" />
</s:Application>
package components{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.MouseEvent;
import mx.controls.Image;
import mx.core.DragSource;
import mx.managers.DragManager;
import spark.components.Label;
import spark.components.supportClasses.SkinnableComponent;
import spark.primitives.supportClasses.FilledElement;
public class ProductItem extends SkinnableComponent{
[SkinPart(required="true")]
public var imageElement:FilledElement;
[SkinPart(required="true")]
public var titleElement:Label;
[Bindable]
public var title:String;
[Bindable]
public var color:uint;
public function ProductItem(){
super();
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true);
}
/*
//使用默认的拖动代理
protected function onMouseDown(event:MouseEvent):void{
var ds:DragSource = new DragSource();
ds.addData(this, "product");
DragManager.doDrag(this, ds, event);
}
*/
/**
* 使用自定义的拖动代理(拖动图片和本体相同)
*/
protected function onMouseDown(event:MouseEvent):void{
var screenshot:BitmapData = new BitmapData(width, height);
screenshot.draw(this);
var proxy:Image = new Image();
proxy.source = new Bitmap(screenshot.clone());
var ds:DragSource = new DragSource();
ds.addData(this, "product");
DragManager.doDrag(this, ds, event, proxy);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>[HostComponent("components.ProductItem")]</fx:Metadata>
<s:layout><s:VerticalLayout /></s:layout>
<s:Rect id="imageElement" width="50" height="50">
<s:fill><s:SolidColor color="{hostComponent.color}" /></s:fill>
</s:Rect>
<s:Label id="titleElement" text="{hostComponent.title}" />
</s:Skin>
package components{
import flash.events.Event;
import mx.events.DragEvent;
import mx.managers.DragManager;
import spark.components.Group;
import spark.components.Label;
import spark.components.supportClasses.SkinnableComponent;
import spark.filters.BlurFilter;
[SkinState("noitems")]
[SkinState("items")]
public class ShoppingCart extends SkinnableComponent{
[SkinPart(required="true")]
public var titleElement:Label;
[SkinPart(required="true")]
public var contentGroup:Group;
[Bindable]
public var title:String;
protected var _itemCount:uint = 0;
[Bindable(event="itemCountChanged")]
public function get itemCount():uint{ return _itemCount; }
public function ShoppingCart(){
super();
addEventListener(DragEvent.DRAG_ENTER, onDragEnter, false, 0, true);
addEventListener(DragEvent.DRAG_DROP, onDragDrop, false, 0, true);
addEventListener(DragEvent.DRAG_EXIT, onDragExit, false, 0, true);
}
/**
* 拖动对象进入
*/
protected function onDragEnter(event:DragEvent):void{
if(event.dragSource.dataForFormat("product") is ProductItem){
DragManager.acceptDragDrop(this);
filters = [new BlurFilter()];
}
}
/**
* 拖动对象移出
*/
protected function onDragExit(event:DragEvent):void{
filters = [];
}
/**
* 拖动对象放置
*/
protected function onDragDrop(event:DragEvent):void{
var element:ProductItem = event.dragSource.dataForFormat("product")
as ProductItem;
contentGroup.addElement(element);
_itemCount = contentGroup.numElements;
dispatchEvent(new Event("itemCountChanged"));
invalidateSkinState();
filters = [];
}
override protected function getCurrentSkinState():String{
return _itemCount == 0 ? "noitems" : "items";
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>[HostComponent("components.ShoppingCart")]</fx:Metadata>
<s:states>
<s:State name="noitems" />
<s:State name="items" />
</s:states>
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="white" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color.noitems="black" color.items="#de7800"
weight="2"/>
</s:stroke>
</s:Rect>
<s:VGroup left="5" right="5" top="5" bottom="5">
<s:Label id="titleElement" width="100%"
color="black"
fontSize="14" fontWeight="bold"
text.items="{hostComponent.title} ({hostComponent.itemCount})"
text.noitems="{hostComponent.title}"/>
<s:Group id="contentGroup" width="100%" height="100%">
<s:layout>
<s:VerticalLayout/>
</s:layout>
</s:Group>
</s:VGroup>
</s:Skin>
全部评论(0)