天天看點

初學Flex的Layout機制舉報

[size=medium]Flex的Layout機制具體的說就是Flex對元件的大小和位置的控制算法。從Flash開始初學Flex,也許會對Flex中設定元件的大小有些不适應。在Flash中,DisplayObject的width和height會根據DisplayObject所包含的“可視化元素”的大小自動調整,例如mc中的children的移動或者縮放都可能引起mc的width和height變化,而如果直接改變mc的width和height,會使mc内的可視化元素放大或縮小(但不會引起可視化元素重組),mc的scaleX和scaleY也同時改變。在Flex中,元件的width和height已經被override,是以其表現和Flash有所不同:Flex中組建width和height不一定根據可視化元素大小而定,例如設定了精确大小的Container,即使其内部的可視化元素超出了Container的範圍,Container的大小仍然是指定的精确值,同樣的設定Flex控件的width和height時,不是對控件可視化元素的縮放,通常都會引起可視化元素重畫成新的大小,而不引起scaleX和scaleY的變化。

以前從來沒想過override能有那麼大的“威力”,是以被Flex的width和height搞的糊裡糊塗的,呵呵看來菜鳥就是菜鳥,還好随着不斷的學習總算逐漸更領會到OOP的概念和Flash與Flex這些差别。發了點小感慨作為開場白,接下來就說說初學Flex的Layout機制的一些收獲吧。

設定Flex元件的大小的方式有三種:精确大小explicit sizing、預設大小default sizing、百分比大小percent sizing。精确大小是指通過ActionScript或者MXML明确設定了元件的width或height為多少像素,是一個精确值;預設大小指的是沒有通過ActionScript或者MXML設定元件的width或height;百分比大小是指通過ActionScript設定了元件的percentWidth或percentHeight,也可以通過MXML設定元件的width或height為一個百分數。

Flex元件大小有以下幾種:

1.實際大小:也就是最終顯示出來的元件的大小,可以通過width和height指定和獲得;

2.精确大小:也就是通過精确大小的方式設定元件大小時,所指定的值,可以通過explicitWidth和explicitHeight獲得;

3.預設大小:也就是Flex自動計算出的元件大小,可以通過measuredWidth和measuredHeight獲得,如果設定元件的大小為預設大小時,那麼元件的預設大小也就是實際大小;

4.百分比大小:也就是通過百分比大小的方式設定元件大小時,所指定的值,可以通過percentWidth和percentHeigh指定和t獲得;

5.元件大小的範圍:也就是限制元件的大小應該處于某個區間内,可以通過minWidth、maxWidth、minHeight和maxHeight指定和獲得這個區間。

知道了Flex元件大小的設定方式合類型之後,再了解一下Flex的Layout流程。Layout流程分為三步,第一步是重新整理元件的屬性,稱為Commitment Pass。第二步是在元件屬性更新後,從DisplayList中最深層的元件開始,計算每個元件的測量大小,即檢視控件使用的是精确大小還是預設大小,并擷取相應的值,這一步稱為Measurement Pass。第三步是從DisplayList中的最外層也就是Application開始向内計算每個元件的實際的大小,并完成對控件的大小和位置設定,同時也觸發控件的重畫等方法,這個過程叫做Layout Pass。

這麼多和大小相關的東西,相對Flash确實複雜多了,但是有了這些東西,才讓Flex的Layout相對Flash更自動化。在實際使用時,不同的大小設定方式如何産生影響?這就需要更具體概述一下了。

1.采用精确大小的方式設定元件大小

當使用者明确指定了元件的width和height的像素值時,布局時Flex就會強制使用使用者指定的像素值,注意這種設定是強制的,Flex會保證元件的實際大小width和height就等于設定值,并且指定的大小不受元件大小的範圍限制。在使用者通過width和height設定精确大小時,同時也就設定了元件的explicitWidth和explicitHeight。

2.采用預設大小的方式設定元件大小

當使用者不設定元件width和height,也不設定元件的percentWidth和percentHeigth時,布局時就自動計算元件的大小,也就是使用元件的預設值作為元件的實際大小。不同元件有不同的預設值,元件的預設值也會因為某些屬性改變而改變,例如Button的預設值就與button的label字元長度有關,并且元件的預設大小一定會在[minWidth,maxWidth]和[minHeight,maxHeight]之間,但不一定就是這個區間内的最小值。

3.采用百分比大小方式設定元件大小

當使用者使用百分比的方式指定了元件的大小時,布局時将使用空間的百分比大小。元件的百分比大小是建議性的,Flex隻是盡量保證元件的大小與parent的可視區域大小成所設定的比例。有以下幾點需要注意:

元件的百分比大小和精确大小是互斥的屬性,當設定了元件的percentWidth和percentHeight時,相應的explicitWidth和explicitHeight屬性就是NaN,反之亦然。而width和height指的是元件在布局過程執行完成後實際的長寬,并不會因為設定了百分比大小就為NaN。隻是通過width和height設定精确大小時,會同時設定explicitWidth和explicitHeight屬性,進而使percentWidth和percentHeight屬性為NaN。

元件百分比大小指的是相對其parent中的可視區域的大小的百分比,也就是刨除parent的border width、padding、gap等區域後(gap個數會根據元件數量而定),用于放置元件的那個區域的大小,并不是parent的實際大小。對于Tile container或者TileLayout,children的百分比是指相對于每個tile cell的百分比,對于其它大部分Container,百分比是相對于整個容器可視區域的。

當元件設定為百分比大小時,元件的實際大小是在parent的大小調整過程中計算出來的,如果按照設定的比例超出了元件的minimum size和maximun size範圍,那麼元件會被設定成minimum size或maximun size(元件的minimum size會根據元件群組件所包含的child不同而不同),而不是百分比指定的大小(是以百分比大小隻是一個建議值)。

當元件設定為百分比時,如果元件的parent是自動布局的,并且還包含了其它元件,那麼parent會先保證設定為精确大小和預設大小的child元件以及parent相應的border width、padding和gap先配置設定空間;對于設定成百分比大小的child元件,會根據parent的可視區域大小(排除border width、padding和相應數量的gap之後的區域大小)嘗試按照設定的百分比設定元件的大小,但是如果這些元件的大小超出了parent剩餘的空間,那麼parent會把剩餘空間按照元件的百分比所構成的比例,配置設定給每個百分比元件(同時也要保證元件大小在minimum size或maximun size之間)。例如Hbox的實際寬度是400(确定實際寬度時,是先layout pass過程,先确定parent才确定child),包含左右padding各50,包含一個設定了寬度為120的button,parent的gap為40,還有兩個設定了寬度為60%和30%的元件,那麼計算這兩個元件實際寬度時,首先配置設定一個button和左右padding以及2個gap(3個元件是以有2個gap)的空間,總大小為120 + 2×50 + 2×40 = 300,parent中剩餘的區域還有100。根據百分比兩個元件的大小是(400- 2×50 - 2×40)×60%和(400- 2×50 - 2×40)×30%,分别為132和66,但是132+66大于parent剩餘的空間,是以,parent把剩餘的100空間分為兩個分給兩個元件,60%的元件分到的空間是100×60/(60+30),30%的元件分到的空間是100×30/(60+30),分别是67和33,配置設定到的大小滿足在minimum size或maximun size之間,是以最終元件的實際大小就是這個值。如果手動設定兩個百分比元件的minimum size為70和50,那麼67和33就不滿足可取的值範圍,是以元件實際大小會被設定為70和50,這樣就會超出HBox的可視區域,由此就會出現滾動條(也可以設定不出現滾動條)。

當元件設定為百分比時,如果元件的parent是絕對布局的,對于halo Container的child,會根據parent的可視區域大小乘以百分比計算實際大小,同時還考慮minimum size或maximun size限制,也考慮元件的位置,保證元件處于哪個位置上時實際大小不會超出parent的邊界。對于spark Container的child,會根據parent的可視區域大小乘以百分比計算實際大小,同時還考慮minimum size或maximun size限制,但不考慮child自身位置的影響。[/size]

繼續閱讀