2012-09-16 31 views
3

我正在構建遞歸層次佈局。這是我的message_with_replies.xml(我已經刪除對齊屬性和一些項目,使思想明確):如何優化遞歸嵌入式佈局?

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" > 
    <Button 
     android:id="@+id/toggleReplies" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/button_expand_replies" /> 
    <LinearLayout 
     android:id="@+id/replies" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" > 
    </LinearLayout> 
</RelativeLayout> 

在Java代碼中,我膨脹的物品用這個佈局並將其嵌入到回覆父的佈局,然後重複這個與孩子們,讓他們形成一個樹:

root item 
- child 0 of root 
- - child 0 of child 0 of root 
- - child 1 of child 0 of root 
- - - child 0 of child 1 of child 0 of root 
- child 1 of root 
- child 2 of root 
- child 3 of root 
- - child 0 of child 3 of root 

一切看起來,當我在頂層或從頂部約2-3個級別進行罰款,但隨着我走得更深,佈局響應越來越慢。減速是非線性的,並且在大約7或8的深度處,UI完全阻塞(模擬器在思考大約半分鐘後引發異常)。

很顯然,問題在於嵌入式佈局。我將線性佈局嵌入到相關佈局中,因此,根據UI佈局,我的層次結構的每個新層次都意味着兩個額外的嵌入。

如何優化?

我可以嘗試擺脫線性佈局,但我希望這不會解決問題,但只會推遲到一些更深層次,因爲我仍然會有嵌入。

當我使用其他佈局的子項目膨脹時,通常可以保持層次平坦嗎?我可以充氣物品,然後在沒有容器的情況下取出物品嗎?

加:我繞過了這個問題。現在我使用邊距構建我的樹,所以佈局沒有嵌入,並且UI不會卡住。一切看起來和工作正常。

但是原來的問題還沒有回答。

+0

您提出的平面視圖層次*實際上是對原始問題的有效答案。你原來的問題可以解釋爲「我正在做這個非常昂貴的操作,我怎麼能優化它?」有時候,正確的答案是「減少工作量」。 Android中佈局過多的圖層總是很昂貴。 – kabuko

回答

3

一切看起來,當我在頂層或從頂部約 2-3個級別進行罰款,但我走得更深,佈局響應 慢。減速是非線性的,並且在大約7或8的深度處,UI完全陷入困境(仿真器在思考大約半分鐘後引發了 異常)。

正如你已經看到的問題是你的佈局文件的部門。每次你膨脹message_with_replies.xml並將其添加到LinearLayout你增加你的佈局部2(這會降低性能)。所以,當你達到7-8的水平時,你已經超過了推薦的最大布局部分(如果我沒有弄錯的話10)。

如何優化?

如果你想繼續膨脹舊視圖的佈局然後沒有太多的事情要做。否則,您可以將視圖添加到主佈局,而不需要額外的ViewGroups

當我給一個 子項添加其他佈局時,通常可以保持層次不變嗎?我是否可以充氣該物品,然後在沒有其容器的情況下取出其內容 ?

如果您只將Views添加到版面,您將保持層次平坦。只要你添加ViewGroupsViewGroups(就像你在你的代碼中做的那樣),你就會增加層次結構的部分。避免添加不必要的ViewGroups(在某些情況下)的選項是使用merge標記(您可以找到更多詳細信息here)。

補充:我繞過了這個問題。現在我使用邊距構建我的樹, 因此佈局未嵌入,並且UI不會卡住。一切 看起來和工作正常。

這應該是你的第一個選擇,而不是一次又一次地使佈局膨脹,因爲它是一個更簡單的解決方案。可以通過使用簡單的LinearLayout(或RelativeLayout,我不知道您的設置,因爲您從佈局中刪除佈局屬性)使用orientation設置爲vertical來獲取佈局。在此佈局中,您將添加所需的視圖,並考慮根據您希望此孩子的級別添加邊距。如果你想更簡化的東西,你將創建類似下面的佈局文件(這個作品,如果從佈局中Button被設置爲在LinearLayout的頂部):

<merge> 
    <Button android:id="@+id/toggleReplies"> 
    <!-- content of the replies at this level --> 
</merge> 

你吹這個佈局後,您會需要設置填充(第一級爲x填充,第二級爲2x,第三級爲3x等),然後將其添加到LinearLayout

+0

那麼,真正的填充不是我想要的,因爲我需要繪製子節點之間的連接線,所以我通過在該項左側的佈局中插入一些圖像來構建填充。但總體思路很明確,謝謝。所以我最終的解決方案似乎是正確的(也是唯一可能的)。 –