Flex中的拖动技术

 

 Flex中的拖动技术

 

 

网上发现这篇文章很详细,稍作补充整理下!

组件的拖动分为:加强型(即本身就可以拖动设置是否可以拖动的属性即可),非加强型(可以通过DragManager,DragEvent,DragSource三个类来实现)

下面详细讲解常见的拖动,案例比较多,可以自行类推和拓展!

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" fontSize="12">
<mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;
        import mx.core.IUIComponent;
        import mx.events.DragEvent;
        import mx.core.DragSource;
        import mx.managers.DragManager;
      
        [Bindable]
        private var listData:ArrayCollection = new ArrayCollection();
        //拖动初始器
        private function dragSource(myData:String,e:MouseEvent,format:String):void
        {
           var iu:IUIComponent = e.currentTarget as IUIComponent;
            var ds : DragSource = new DragSource();
            ds.addData(myData,format);//设置一个标号format
            DragManager.doDrag(iu,ds,e); // 开始拖动这个物体
        }
        //当拖进去时
        private function onEnter( e:DragEvent,format:String ) : void
        {
            if(e.dragSource.hasFormat(format))//如果标号为format则接受拖来的物体
            {
                DragManager.acceptDragDrop(IUIComponent(e.target) );// 接受被拖进来的物体      

  
            }
        }
        //当拖完成时
        private function onDrop(e:DragEvent,format:String) : void
        {
            var myData:Object = new Object();
            myData = e.dragSource.dataForFormat(format);
            list1.dataProvider.addItem(myData);//list1是List的id,要是扩展到其他组件,改这里就可以了。
        }
    ]]>
	</mx:Script>
    <mx:Label text="拖动我到List" width="86" height="27" id="lbl" mouseDown="dragSource('这个是一个label',event,'stringFormat')"/>
    <mx:List dataProvider="{listData}" id="list1" dragEnter="onEnter(event,'stringFormat')"
		dragDrop="onDrop(event,'stringFormat')" width="206">
	</mx:List>
        <!--文档注释-->
     </mx:Application>

Flex组件内置了处理拖拽事件的接口,有些控件已经实现了拖拽功能,比如List、DataGrid、Menu、

HorizontalList、 PrintDataGrid、TileList、Tree,在设置相关的拖拽属性后,它们都可以在相同类型的组
件之间利用鼠标来实现数据的转移。
allowDragSelection           是否可以拖选
allowMultipleSelection       是否可以多选
dragEnabled                     是否可以拖动子元素
dragMoveEnabled              是否移动元素位置,而不是复制元素
dropEnabled                     是否可以将物体放置进来


在Flex中,有几个专门的对象供开发者处理拖拽事件:
DragManager:位于mx.managers包中,管理拖拽事件
DragSource:   位于mx.core包中,是Flex框架中的核心成员,处理拖拽中的数据传递
DragEvent:     位于mx.events包中,拖拽操作中的事件对象。


按照逻辑,拖拽中至少有两个对象:一方提供数据,一方接收数据。在这个过程中,提供数据的一方按照前后
顺序,可以把整个过程划分为下面几个事件:

mouseDown:鼠标按下。
mouseMove:鼠标移动。
dragComplate:鼠标释放。判断目标是否接受数据,如果可以,拖放成功。


接收方也将经历几个阶段
dragEnter:被拖动对象移动到目标范围中。
dragDrop:鼠标在目标上松开。
dragOver:鼠标移动到目标上。
dragExit:独享被拖离目标范围。


1.   Tree与Tree之间的拖动:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="vertical"
				verticalAlign="middle">

	<mx:XML id="myData">
		<data>
			<item label="ActionScript">
				<item label="Flash"/>
				<item label="Flex"/>
			</item>
			<item label="Mirage">
			</item>
			<item label="JavaScript"/>
		</data>
	</mx:XML>

	<mx:XML id="copyData">
		<data>
			<item label="JavaScript"/>
		</data>
	</mx:XML>

	<mx:Tree dropEnabled="true"
			 dragEnabled="true"
			 dragMoveEnabled="true"
			 allowMultipleSelection="true"
			 dataProvider="{myData.item}"
			 labelField="@label"/>

	<mx:Tree dropEnabled="true"
			 dataProvider="{copyData.item}"
			 labelField="@label"/>
</mx:Application>


 

上面代码中只需设置
dropEnabled="true" //是否可以将被拖动的物体放置进来
dragEnabled="true" //是否可以拖动子元素
dragMoveEnabled="true" //是否只是移动元素,而不是复制元素
allowMultipleSelection="true" //是否可以多项拖动元素,为true时可以用ctrl选多个一起拖动


List与List之间的拖动,只要设置上面的就可以了。
DataGrid 拖动到DataGrid和List

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="vertical"
				verticalAlign="middle"
				fontSize="12">

	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.events.DragEvent;

			[Bindable]
			private var mylist:ArrayCollection;

			//当拖完成时
			private function onDrop(e:DragEvent):void
			{
				var myData:Object=new Object();
				myData=e.dragSource.dataForFormat('items'); //从dragSource中拿到条目
				var name:String=myData[0].name; //注意这个地方必需要用变量进行替换
				list1.dataProvider.addItem(name);
				e.preventDefault(); //可以去掉默认的数据转移
			}
		]]>
	</mx:Script>

	<mx:XMLList id="employees">
		<employee>
			<name>小马</name>
			<phone>13042334532</phone>
			<email>[email protected]</email>
		</employee>
		<employee>
			<name>张春</name>
			<phone>13642987532</phone>
			<email>[email protected]</email>
		</employee>
		<employee>
			<name>小李</name>
			<phone>13923485844</phone>
			<email>[email protected]</email>
		</employee>
	</mx:XMLList>

	<mx:DataGrid x="10"
				 y="15"
				 width="277"
				 id="dg"
				 rowCount="5"
				 dataProvider="{employees}"
				 dragEnabled="true">
		<mx:columns>
			<mx:DataGridColumn headerText="Name"
							   dataField="name"/>
			<mx:DataGridColumn headerText="Email"
							   dataField="email"/>
			<mx:DataGridColumn headerText="Phone"
							   dataField="phone"/>
		</mx:columns>
	</mx:DataGrid>

	<mx:DataGrid dropEnabled="true">
		<mx:columns>
			<mx:DataGridColumn headerText="Name"
							   dataField="name"/>
			<mx:DataGridColumn headerText="Email"
							   dataField="email"/>
			<mx:DataGridColumn headerText="Phone"
							   dataField="phone"/>
		</mx:columns>
	</mx:DataGrid>

	<mx:List height="210"
			 width="206"
			 id="list1"
			 dropEnabled="true"
			 dataProvider="{mylist}"
			 dragDrop="onDrop(event)">
	</mx:List>

	 		 </mx:Application>

2.非加强拖动技术
Label的拖动,可以扩展到其他组件


 

Button的拖动,可以扩展到其他组件

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="vertical"
				verticalAlign="middle"
				fontSize="12">
	<mx:Script>
		<![CDATA[
			import mx.core.IUIComponent;
			import mx.events.DragEvent;
			import mx.core.DragSource;
			import mx.managers.DragManager;

			//拖动初始器
			private function dragSource(e:MouseEvent, format:String):void
			{
				var iu:IUIComponent=e.currentTarget as IUIComponent;
				var ds:DragSource=new DragSource();
				ds.addData({"x": e.localX, "y": e.localY}, format); //设置一个标号format
				DragManager.doDrag(iu, ds, e);
			}

			//当拖进去时
			private function onEnter(e:DragEvent, format:String):void
			{
				if (e.dragSource.hasFormat(format)) //如果标号为format则接受拖来的物体
				{
					DragManager.acceptDragDrop(IUIComponent(e.target));
				}
			}

			//当拖完成时
			private function onDrop(e:DragEvent, format:String):void
			{
				var myData:Object=new Object();
				myData=e.dragSource.dataForFormat(format);
				btn.x=this.mouseX - myData.x; //btn为按钮的id,要是扩展到其他组件,改这里就可以了。
				btn.y=this.mouseY - myData.y;
			}
		]]>
	</mx:Script>
	<mx:Canvas y="40"
			   id="cansAccess"
			   backgroundColor="#000000"
			   width="300"
			   height="200"
			   dragEnter="onEnter(event,'formatString')"
			   dragDrop="onDrop(event,'formatString')"/>
	<mx:Button id="btn"
			   label="拖动我到面板"
			   mouseDown="dragSource(event,'formatString')"/>
	 </mx:Application>


 

一定要注意,标签的先后位置,Button 要在Canvas 之后.


3.Canvas容器中拖动Box,你还可以在Box中添加图片等。

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="absolute"
				fontSize="12">
	<mx:Script>
		<![CDATA[
			import mx.containers.Box;
			import mx.containers.Canvas;
			import mx.core.IUIComponent;
			import mx.events.DragEvent;
			import mx.managers.DragManager;
			import mx.core.DragSource;

			//拖动初始器
			private function dragSource(e:MouseEvent, format:String):void
			{
				var iu:IUIComponent=e.currentTarget as IUIComponent;
				var ds:DragSource=new DragSource();
				ds.addData(iu, format); //设置一个标号format
				DragManager.doDrag(iu, ds, e); // 开始拖动这个物体
			}

			//当拖进去时
			private function onEnter(e:DragEvent, format:String):void
			{
				if (e.dragSource.hasFormat(format)) //如果标号为format则接受拖来的物体
				{
					DragManager.acceptDragDrop(IUIComponent(e.target)); // 接受被拖进来的物体      
				}
			}

			//当拖完成时
			private function onDrop(e:DragEvent, format:String):void
			{
				var box:Box=Box(e.dragInitiator); //如果扩展到其他组件,改这里Box就可以了。
				box.x=e.localX;
				box.y=e.localY;
			}
		]]>
	</mx:Script>

	<mx:Canvas backgroundColor="0xEEEEEE"
			   width="500"
			   height="246"
			   horizontalCenter="0"
			   verticalCenter="0"
			   dragEnter="onEnter(event,'boxFormat')"
			   dragDrop="onDrop(event,'boxFormat')">
		<mx:Box id="boxDrag"
				width="20"
				height="20"
				backgroundColor="0x00FFCC"
				x="97"
				y="47"
				mouseDown="dragSource(event,'boxFormat');">
		</mx:Box>
	</mx:Canvas>
	 </mx:Application>


 

4.图片的拖动

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="vertical"
				width="100%"
				height="100%"
				fontSize="12">
	<mx:Script>
		<![CDATA[
			private var oldX:Number; //拖动开始是的坐标
			private var oldY:Number;

			//拖动开始
			private function dragStart(event:MouseEvent):void
			{
				oldX=event.stageX; //相对Application的坐标
				oldY=event.stageY;
			}

			//拖动结束
			private function dragEnd(event:MouseEvent):void
			{
				lbl.text="Local (x,y):" + event.localX.toString() + "," + event.localX.toString(); //相对图片的坐标
				lbl2.text="Stage (x,y):" + event.stageX.toString() + "," + event.stageY.toString(); //相对Application的坐标
				if (event.buttonDown)
				{ //如果鼠标在移动过程中并且按下,也就是说鼠标的拖动事件。
					var x:Number=event.stageX - oldX; //相对Application的坐标的移动量
					var y:Number=event.stageY - oldY;
					oldX=event.stageX; //更新拖动开始是的坐标
					oldY=event.stageY;
					img.move(img.x + x, img.y + y); //img是 Image的id,如果扩展到其他组件,改这里就可以了。
				}
			}
		]]>
	</mx:Script>
	<mx:Label x="10"
			  y="10"
			  text=""
			  id="lbl"/>
	<mx:Label x="10"
			  y="27"
			  text=""
			  id="lbl2"/>
	<mx:Panel x="257"
			  y="71"
			  width="700"
			  height="80%"
			  layout="absolute"
			  horizontalScrollPolicy="off"
			  verticalScrollPolicy="off"
			  title="图片在面板中的拖动例子"
			  fontSize="12">
		<mx:Image id="img"
				  x="0"
				  y="0"
				  source="test.JPG"
				  mouseMove="dragEnd(event)"
				  mouseDown="dragStart(event)"/>
	</mx:Panel>
	 </mx:Application>


 

5.从外部拖动到组件,比如从桌面上拖动一个图片到图片组件等。
因为我的flash包中没有flash.events.NativeDragEvent等。所以这里稍作总结。

拖动外部文件

拖动外部文件需要NativeDragEvent,NativeDragManager类。其实用法和上面的DragManager一样,但是往往一个控件既要接受Flex内部被拖进来的控件,还要接受外部拖进来的文件,这时候显得就比较麻烦了。
但是请不要害怕,这里的Clipboard会帮我解决问题。

 

<mx:Canvas y="40" id="cansAccess" backgroundColor="#000000"  width="300" height="200"
 dragDrop="complete(event)" nativeDragDrop="nativeComplete(event)" dragEnter="enter(event)" />
<mx:Button id="btnDrag" label="拖动我"
 mouseDown="doDrag( event )" />

按理来说当拖动内部控件的时候会触发dragDrop事件,拖动外部文件会触发nativeDragDrop事件,事实上,不管你拖动外部文件还是内部控件都会触发这两个事件。这里我们使用Clipboard来解决这一麻烦


 

private function doDrag( e : MouseEvent ) : void
{
 var ds : DragSource = new DragSource;
 ds.addData( {"x" : e.localX, "y" : e.localY},"xy");
 DragManager.doDrag(btnDrag,ds,e);
}
private function enter( e  :DragEvent ) : void
{
 DragManager.acceptDragDrop( Canvas(e.target) );
 NativeDragManager.acceptDragDrop(Canvas(e.target));
 //使其接受从外部拖进来的文件 
}
private function complete( e : DragEvent ) : void
{
 
}
private function nativeComplete( e : NativeDragEvent ) : void
{
 var filesObj : Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT ) as Array;
 //获取剪切板上的文件列表
 if( filesObj &&  filesObj.length > 0)  //符合这一条件说明是从外部拖文件进来  这里假设处理拖进来的是图片
 {
  for each( var item : File in filesObj )
  {
   switch( item.extension )
   {
    case "jpg":
    case "bmp":
    case "gif":
    var img : Image = new Image;     img.source = item.nativePath;     cansAccess.addChild( img );
    break;   
   }
  }
 }
 else   //否则的话是就是在拖动内部的控件
 {
  var xy : Object =  e.clipboard.getData(e.clipboard.formats[0]);
  //还记得doDrag 的时候附加的那个 DragSource 么?
  //这里因为不能用e.dragSource.dataForFormat("xy")了因为事件不一样,
  //但我们还是可以用剪切板来取得这个值
  btnDrag.x =  e.localX - xy.x + cansAccess.x;
  btnDrag.y =  e.localY - xy.y + cansAccess.y;
 }
}






6.引入dNdLib.swc库让拖动变得更简单
Flex开放了它的拖拽库(即:flex-drag-n-drop-lib),我们可以利用它做一些很有用的拖拽应用,下面我们

来做一个简单的示例,按照下述的步骤,你会了解到在Flex中使用flex-drag-n-drop-lib的技巧。
1.点击这里下载SWC组件到你的桌面。
2.打开FlexBuilder,新建一个Flex Project,在第三步的Library Path选项中,点击Add SWC按钮,将刚才下

载到的SWC组件引入到项目中。


3.点击Finish,在自动创建的MXML文件中,敲入以下代码:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="absolute"
				xmlns:containers="dNdLib.containers.*"
				fontSize="12">
	<mx:Script>
		<![CDATA[
			import dNdLib.managers.DnDManager;
		]]>
	</mx:Script>
	<containers:DnDContainer borderStyle="solid"
							 id="left"
							 backgroundColor="#FFFFFF"
							 width="161"
							 height="237"
							 x="110"
							 y="168">
		<mx:Button label="拖动我"
				   mouseDown="DnDManager.getInstance().doDrag(event)"
				   width="92"
				   height="32"/>
		<mx:CheckBox label="拖动就这么简单"
					 mouseDown="DnDManager.getInstance().doDrag(event)"/>
	</containers:DnDContainer>

	<containers:DnDContainer borderStyle="solid"
							 id="bottom"
							 backgroundColor="#FFFFFF"
							 x="415"
							 y="168"
							 width="140"
							 height="237"/>
</mx:Application>

然后Run一下看看结果吧,组件可以拖动了。很简单吧。
注意:必须为DnDContainer设置一个背景色(backgroundColor=color),否则可能无法产生相应区域。

你可能感兴趣的:(datagrid,String,function,Flex,application,encoding)