当前位置: > > > Flex4 - 自定义组件增加拖放行为

Flex4 - 自定义组件增加拖放行为

Flex自带的List等组件默认就有拖放行为。而对于自定义的组件,通过DragManager也可以添加拖放行为。
下面是一个购物车的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>

--- 产品类 ProductItem.as ---
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);
    }
  }
}

--- 产品皮肤 ProductItemSkin.mxml ---
<?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>

--- 购物车类 ShoppingCart.as ---
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";
    }
  }
}

--- 购物车皮肤 ShoppingCartSkin.mxml ---
<?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