`
pyleaf
  • 浏览: 39811 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Tile 容器内部拖拽

    博客分类:
  • Flex
 
阅读更多

本例是Flex3 Cookbook 3.27节的内容,需求是要让用户可以在Tile 容器里面拖拽其瓷砖(tile)并且在用户放下瓷砖(tile)的时候容器重组。

书中示例代码如下:

<mx:Tile xmlns:mx="http://www.adobe.com/2006/mxml" width="300"
height="600" direction="horizontal">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
private function childStartDrag(event:Event):void
{
(event.currentTarget as UIComponent).startDrag(false,
this.getBounds(stage));
(event.currentTarget as
UIComponent).addEventListener(MouseEvent.MOUSE_UP,
childStopDrag);
(event.currentTarget as
UIComponent).addEventListener(MouseEvent.ROLL_OUT,
childStopDrag);
swapChildren((event.currentTarget as UIComponent),
getChildAt(numChildren-1));
}
private function childStopDrag(event:Event):void
{
swapChildren((event.currentTarget as UIComponent),
hitTestChild((event.currentTarget as UIComponent)));
(event.currentTarget as UIComponent).stopDrag();
this.invalidateDisplayList();
this.invalidateProperties();
}
private function
hitTestChild(obj:UIComponent):DisplayObject
{
for(var i:int = 0; i<this.numChildren; i++)
{
if(this.getChildAt(i).hitTestObject(obj))
{
return getChildAt(i);
}
}r
return getChildAt(0)
}
]]>
</mx:Script>
<mx:Panel title="First Panel"
mouseDown="childStartDrag(event)">
<mx:Text text="First Text"/>
</mx:Panel>
<mx:Panel title="Second Panel"
mouseDown="childStartDrag(event)">
<mx:Text text="Second Text"/>
</mx:Panel>
<mx:Panel title="Third Panel"
mouseDown="childStartDrag(event)">
<mx:Text text="Third Text"/>
</mx:Panel>
<mx:Panel title="Fourth Panel"
mouseDown="childStartDrag(event)">
<mx:Text text="Fourth Text"/>
</mx:Panel>
</mx:Tile>

 

 

本着学习Flex4的原则,将本书中的例子用Flex4控件加以改造,但是运行起来各种问题(事实上,书中的代码在Flex3中运行也是各种问题),最主要是swapChildren方法在Flex4中对应的swapElements方法执行后会自动替换两个控件的位置,导致无法拖拽,若不调用该方法,则顺序靠前的控件在拖拽的过程中会与顺序靠后的控件重叠一部分,导致无法拖放,于是乎开始改造。

使用拖拽代理,可解决控件重叠的问题。本来是想另拖拽源控件隐藏,但是在拖拽失败时候无法重新显示出来,因此暂不考虑。

代码如下:

<?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:mx="library://ns.adobe.com/flex/mx"
			   minWidth="955"
			   minHeight="600">
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
	<fx:Script>
		<![CDATA[
			import mx.core.BitmapAsset;
			import mx.core.DragSource;
			import mx.core.UIComponent;
			import mx.events.DragEvent;
			import mx.events.FlexEvent;
			import mx.managers.DragManager;

			private var targetElem:UIComponent;

			private function childStartDrag(event:MouseEvent):void {
				var ui:UIComponent = event.currentTarget as UIComponent;
				var proxyBox:BitmapAsset = new BitmapAsset();
				proxyBox.bitmapData = new BitmapData(ui.width, ui.height);
				proxyBox.bitmapData.draw(ui);
				var ds:DragSource = new DragSource();
				ds.addData(ui, "border");
				DragManager.doDrag(ui, ds, event, proxyBox);
			}

			protected function tg_dragEnterHandler(event:DragEvent):void {
				if (event.dragSource.hasFormat("border")) {
					DragManager.acceptDragDrop(event.currentTarget as UIComponent);
				}
			}

			protected function tg_dragDropHandler(event:DragEvent):void {
				var elem:UIComponent = event.dragInitiator as UIComponent;
				if (targetElem && targetElem != elem) {
					tg.swapElements(targetElem, elem);
				}
			}

			protected function tg_creationCompleteHandler(event:FlexEvent):void {
				for (var i:int = 0; i < tg.numElements; i++) {
					tg.getElementAt(i).addEventListener(DragEvent.DRAG_ENTER, elemDragEnter, false, 0, true);
					tg.getElementAt(i).addEventListener(MouseEvent.MOUSE_DOWN, childStartDrag, false, 0, true);
				}
			}

			protected function elemDragEnter(event:DragEvent):void {
				if (targetElem != event.currentTarget) {
					targetElem = event.currentTarget as UIComponent;
				}
			}
		]]>
	</fx:Script>

	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>

	<s:TileGroup id="tg"
				 dragEnter="tg_dragEnterHandler(event)"
				 dragDrop="tg_dragDropHandler(event)"
				 creationComplete="tg_creationCompleteHandler(event)"
				 x="129"
				 y="58">
		<s:BorderContainer>
			<s:Label text="First Text"/>
		</s:BorderContainer>
		<s:BorderContainer>
			<s:Label text="Second Text"/>
		</s:BorderContainer>
		<s:BorderContainer>
			<s:Label text="Third Text"/>
		</s:BorderContainer>
		<s:BorderContainer>
			<s:Label text="Fourth Text"/>
		</s:BorderContainer>
	</s:TileGroup>
</s:Application>

 

分享到:
评论

相关推荐

    FLEX主要容器关系图

    `GridRow`和`GridItem`是`Grid`容器内部使用的组件,分别代表表格的一行和一个单元格。它们负责具体的数据显示和格式化,是构建复杂表格的关键部分。 ### ApplicationControlBar(应用程序控制栏) `...

    Flex clipContent 编程注意

    在上述问题中,开发者遇到了一个需求,即允许元素C在容器A内自由拖动,但C实际被包含在B容器中,而B容器默认会限制子项的移动范围在自身边界内。此时,`clipContent`属性的作用就显现出来了。 `clipContent`属性...

    flex3的cookbook书籍完整版dpf(包含目录)

    3.27 节用简单重组行为创建Tile 容器 3.28 节给Hbox 设置背景图片和圆角 3.29 节控制子组件的位置和滚动 第四章文本(121) 4.1节正确的设置一个文本对象的值 4.2节. 将TextInput绑定一个值 4.3节. 创建一个具有文字...

    uniapp_map组件

    在实际项目中,你可能还需要处理地图的交互事件,如点击事件、拖动事件等,以及自定义图层、图层控制、弹窗等功能。Leaflet的API非常丰富,能够满足各种地图展示和操作的需求。同时,uniAPP的灵活性让我们能够将这些...

    openlayersDemo

    1. **地图加载**:使用`ol.Map`类创建地图,指定地图容器ID和图层。例如: ```javascript var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view:...

    (0023)-iOS/iPhone/iPAD/iPod源代码-滚动视图(ScrollView)-ScrollXib

    它是一个可以容纳比其实际大小更大的内容视图的容器。通过设置contentSize属性,我们可以指定ScrollView可滚动的范围。在实际应用中,ScrollView常用于实现图片浏览、页面切换、表格视图(UITableView)和集合视图...

    ck-viewer:Chinook Client软件包使用OpenLayers 3为GIS Web查看器界面提供组件

    - **地图容器**:ck-viewer预设了一个用于展示地图的容器,用户可以直接添加图层并进行操作。 - **图层控制**:提供图层列表,用户可以方便地切换和调整图层的可见性和透明度。 - **工具栏**:包括缩放、平移、测量...

Global site tag (gtag.js) - Google Analytics