首頁(yè) > 設計 > WEB開(kāi)發(fā) > 正文

3.24.手動(dòng)布局容器

2023-08-08 22:33:06
字體:
來(lái)源:轉載
供稿:網(wǎng)友
3.24.1 問(wèn)題
你需要根據類(lèi)型以及類(lèi)型的屬性來(lái)布置容器的子組件。
3.24.2 解決辦法
覆蓋UIComponent 的updateDisplayList 方法來(lái)移動(dòng)子組件。
3.24.3 討論
要在任何Container 或者UIComponent 對象內覆蓋任何布局或設置大小的邏輯,只要覆蓋updateDisplayList 方法并在super.updateDisplayList分方法之后插入你自己的布局邏輯即可。本節專(zhuān)注于如何通過(guò)使用子組件的自定義的屬性來(lái)決定Hbox 子組件的布局。這個(gè)例子由4 個(gè)文件組成,三個(gè)類(lèi)和一個(gè)接口,它們各司其職并擁有自己獨有的屬性。大致的UML圖(圖Figure 3-1)描述了它們之間的關(guān)系。

Figure 3-1. Relationships between containers and interfaces

Canvas.mxml 文件內添加了ForceLayout 組件并提供其子組件。ForceLayout 組件可以包含任何子組件,但如果子組件實(shí)現了IspecialLayout 接口,ForceLayout 組件將會(huì )根據此類(lèi)子組件是否被選中來(lái)進(jìn)行不同的布局。SpecialLayoutCanvas 定義了簡(jiǎn)單的方法來(lái)決是否被選中。

首先,看一下SpecialLayoutCanvas.as 文件:
+展開(kāi)
-ActionScript
package oreilly.cookbook
{
import mx.containers.Canvas;
import mx.controls.Label;
import mx.core.UIComponent;
import flash.events.MouseEvent;
public class SpecialLayoutCanvas extends Canvas implements
ISpecialLayout
{
private var titlelabel:Label;
private var selectedlabel:Label;
private var _isSelected:Boolean = false;
public function SpecialLayoutCanvas()
{
super();
titlelabel = new Label();
addChild(titlelabel);
titlelabel.text = "Label";
this.addEventListener(MouseEvent.MOUSE_DOWN,
setIsSelected);
minHeight = 45;
minWidth = 80;
selectedlabel = new Label();
//addChild(selectedlabel);
selectedlabel.text = "Selected";
}
private function setIsSelected(mouseEvent:MouseEvent):void
{
_isSelected ? isSelected = false : isSelected = true;
}
public function set isSelected(value:Boolean):void
{
_isSelected = value;
if(isSelected)
{
addChild(selectedlabel);
selectedlabel.y = 30;
}e
else
{
try{
removeChild(selectedlabel);
}catch(err:Error){}
}i
if(parent != null)
{
(parent as UIComponent).invalidateDisplayList();
}
}
public function get isSelected():Boolean
{
return _isSelected;
}
}
}

這個(gè)類(lèi)使用getter 和setter 方法簡(jiǎn)單地定義了一個(gè)selected 屬性,并且當對象被選中的時(shí)候給其添加一個(gè)標簽,反之刪除這個(gè)標簽。

下一步,我們來(lái)看ForceLayout 組件,它讀取所有的子組件來(lái)判別它們中是否有繼承IspecialLayout 接口的,如果有,是否選中了。
+展開(kāi)
-ActionScript
package oreilly.cookbook
{
import mx.core.EdgeMetrics;
import mx.core.UIComponent;
import mx.containers.VBox;
import mx.containers.Panel;
import mx.containers.Canvas;
import flash.display.DisplayObject;
public class ForceLayout extends VBox
{
public var gap:Number;
public function ForceLayout()
{
super();
}

無(wú)論何時(shí),只要該組件需要重繪的時(shí)候,Flex 框架即調用updateDisplayList 方法。因為重繪的時(shí)候組件需要做的一件事情是重新調整所有子組件的位置,所有調整位置的邏輯都在這里實(shí)現:
+展開(kāi)
-ActionScript
override protected function
updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var yPos:Number = unscaledHeight;
// Temp variable for a container child.
var child:UIComponent;
var i:int = 0;
while(i<this.numChildren)
{
// Get the first container child.
child = UIComponent(getChildAt(i));
// Determine the y coordinate of the child.
yPos = yPos - child.height;
// Set the x and y coordinate of the child.
// Note that you do not change the x coordinate.
if(child is ISpecialLayout)
{
if((child as ISpecialLayout).isSelected)
{
yPos -= 20;
child.move(child.x, yPos);
yPos -= 20;
}e
else
{
child.move(child.x, yPos);
}
}e
else
{
child.move(child.x, yPos);
// Save the y
coordinate of the child,
// plus the vertical gap between children.
// This is used to calculate the coordinate
// of the next child.
yPos = yPos - gap;
i++;
}i
= 0;
var amountToCenter:Number = yPos / 2;
while(i<this.numChildren)
{
getChildAt(i).y -= amountToCenter;
i++;
}
}
}
}

最后的清單將兩個(gè)組件付諸使用,將ForceLayout 容器添加到Canvas 并且添加SpecialLayoutCanvas 子組件。注意,如果它們是當前存在的,僅僅改變布局即可,不需要任何特別屬性,任何類(lèi)型子組件都可以添加到ForceLayoutCanvas,并且實(shí)際上所有實(shí)現了IspecialLayout 接口的子組件都是可用的。
+展開(kāi)
-XML
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxmlwidth="800"
height="600xmlns:cookbook="oreilly.cookbook.*">

<cookbook:ForceLayout width="400height="500"
backgroundColor="#ffffff">

<mx:HBox>
<mx:Button label="button"/>
<mx:LinkButton label="link"/>
</mx:HBox>
<cookbook:SpecialLayoutCanvas isSelected="false"
backgroundColor="#c0c0cc"/>

<mx:HBox>
<mx:Button label="button"/>
<mx:LinkButton label="link"/>
</mx:HBox>
<cookbook:SpecialLayoutCanvas isSelected="false"
backgroundColor="#ccc0c0"/>

<cookbook:SpecialLayoutCanvas isSelected="true"
backgroundColor="#cc00cc"/>

<cookbook:SpecialLayoutCanvas isSelected="false"
backgroundColor="#ccc0c0"/>

</cookbook:ForceLayout>
</mx:Canvas>
發(fā)表評論 共有條評論
用戶(hù)名: 密碼:
驗證碼: 匿名發(fā)表