cocos2d-x的LayoutParameter佈局深入理解

峻峰飛陽發表於2016-11-21

之前理解的不深,今天遇到一個坑,收穫了一些更深的理解。

需求是這樣:一個相對佈局的Panel,裡面有個ImageView,介面其他地方有幾個按鈕,按下去後需要動態地改變這個ImageView的位置。

按照往常的理解,按鈕事件得到觸發後,無非這樣操作就可以了嘛:

node:getLayoutParameter():setMargin({ left = 10, right = 0, top = 0, bottom = 0 })

可是,這句話居然不起作用!把這句話移到UI建立時的那一堆程式碼裡,卻又起作用了!好奇怪,於是我就掉進這個坑裡了。

後來也不知道怎麼的腦門靈感一閃,在Layout類裡看到了一個 requestDoLayout() 方法,於是將程式碼改成這樣,終於生效了:

node:getLayoutParameter():setMargin({ left = 10, right = 0, top = 0, bottom = 0 })
node:getParent():requestDoLayout()

我的理解是,在一個相對定位的Panel裡,如果是在UI建立期間(也即第一幀的時候),無論怎麼搞這個Panel裡面的子節點,它們都會生效,完全不需要手動執行 requestDoLayout() 方法去請求Panel重新定位,因為這個時候Panel是在OnEnter狀態,內部是dirty狀態。而當UI已經建立好了之後(也即第一幀完成了),這個時候要再去更改Panel裡的子節點位置,Panel感知不到變化

,內部不是dirty狀態,不會重新對子節點定位,所以需要手工地請求一次 requestDoLayout() ,讓Panel對子節點新的設定生效。

一個有趣的實驗是這樣:建立一個Panel,相對定位,建立一個ImageView子節點node,左對齊、上對齊(只要不是居中就行,因為設定為居中後就固定死不能動了),建立好之後,隨便找一個按鈕A做個事件,這麼寫:

node:setPositionX(100)

點選按鈕觸發事件,你會發現node的位置發生變化了。然後把再加一個按鈕B,觸發事件裡這麼寫:

node:getParent():requestDoLayout()

先點按鈕A,node位置變了,再點按鈕B,會發現node又跑回原位置了,哈哈。

總結:要在相對定位的Panel裡用程式動態改變位置,避免使用 setPosition() ,而依然要使用LayoutParameter的setMargin()方法,只不過,還要再對Panel做一下 requestDoLayout() 呼叫,通知Panel去重新梳理一遍子節點

相關文章