Flex 流式布局 之 捲軸篇
flex 架構支援流式布局,什麼是流式布局呢,就是在運行時對象的大小是未知的,它可能需要由他的內容(childs)或由它的容器來決定它的實際大小。flex 中有兩種流式一種就是 百分比形式的(percentWidth),還以一種就是預設的 measuredWidth。
那麼這個流式布局又和捲軸有什麼聯絡呢?看一下以百分比形式的例子
<?xml version="1.0"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" xmlns:local="*"> <mx:Script> <![CDATA[ import mx.controls.Button; private function clickHandler():void { var bt:Button = new Button(); inner.addChild(bt); } ]]> </mx:Script> <mx:Button label="Button" click="clickHandler()"/> <mx:HBox width="100%" height="100%" borderStyle="solid" borderThickness="10" paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20"> <mx:HBox width="100%" height="100%" borderStyle="solid" borderThickness="10" paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20"> <mx:HBox id="inner" width="100%" height="100%" borderStyle="solid" borderThickness="10" paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20" borderColor="#43C50A"> </mx:HBox> </mx:HBox> </mx:HBox></mx:Application>
3個HBox width height 都是 100%,當點擊按鈕時,會在最裡面的HBox (id=inner ) addChild 一個button,因為是百分比的流式布局那麼 最裡面的 那個inner在未點擊前的大小是由它的parent決定的,這時它實際上是有了已經計算過的measureWidth 和 measureHeight了,但是當有child(這裡是button)加入後,它的measure值會變嗎?看一
直到加了5個之後inner的measure值都沒變,但是在加第6個時候inner的measure值變了,因為child的視圖範圍超出了它原來的大小所以就把inner撐大了,從而有導致inner的parent的視圖範圍超出了inner的parent原來的大小所以inner的parent也被撐大了,就這樣一直傳到最外面一層,也就是Application,但是Application是有固定大小的是player給它的。
為什麼會這樣的呢?為什麼,捲軸被加到最外層了,而我想讓他出現在最裡層怎麼辦?
首先,來看一下,在第一次inner addchild時發生了寫什麼。
1.override mx_internal function addingChild(child:DisplayObject):void
inner.invalidateSize();
inner.invalidateDisplayList();
標記inner下一個更新要重新算次村和布局
2.override mx_internal function childAdded(child:DisplayObject):void
child.initialize();
child.invalidateProperties();
child.invalidateSize();
child.invalidateDisplayList();
flex架構層級生命週期開始
3.(這裡只看尺寸和布局相關的),受LayoutManger控制,執行順序是
child.invalidateSize();
inner.invalidateSize();
inner.invalidateDisplayList();
child.invalidateDisplayList();
這個順序和程式剛開始的順序是一樣的,commit從外到裡面,在由measue從裡面到外面,在由updatDispalyObject從外到裡面。
4.child.invalidateSize();會得到button的尺寸,這裡button沒有給他具體值,它將採用它的預設值作為它的高寬
然後inner.invalidateSize();在layoutManager的管理下執行inner.validateSize() 做寫什麼事情呢,先執行 HBox的布局管理對象layoutObject.measure(),做寫什麼事情呢,計算inner自己的measure,包括剛剛加進來的buttom 和一些gap,然後根據meause出來的值 判斷inner的大小有沒有變,如果變了還會調用parent.invalidateSize();parent.invalidateDisplayList(); 在執行到inner.invalidateDisplayList();這裡會設定inner的大小了(是在public function validateDisplayList():void)
好暈哦,問題的關鍵是什麼呢,就在最後一次 addChild 後inner measure出來的值變了,從而導致inner變大了,所以就往外擠,一直把捲軸推到最外面一層。
像這樣,
那如果想這樣,就是這幾個嵌套的HBox已經建立了,往inner裡面加button,只在inner原有的基礎上加捲軸呢?
很簡單,就是在 inner的layoutObject.measure()時候對於百分比的情況的計算,或則乾脆去掉inner.measuer()
對於百分比流式布局的inner的大小讓parent去控制,好來看一下。
override protected function measure():void{};
可以了。
原文地址:http://chaimzane.javaeye.com/blog/382411