2011-08-10 25 views
6

有沒有一種方法可以遞歸地從佈局中刪除視圖?函數removeAllViewsInLayout()似乎沒有做任務(它從佈局中刪除所有視圖,但不是佈局的子視圖)。在我的程序中,我通過RelativeLayout動態添加了一些FrameLayouts,並在這些FrameLayouts上添加了一些ImageViews和TextViews。所以我想知道如果我必須去做我自己的遞歸刪除視圖代碼或者如果有一些可用的。Android - 以遞歸方式刪除佈局中的視圖

+0

您是否嘗試刪除FrameLayouts而不是TextViews/ImageViews,然後回滾到FrameLayout? – Rob

+0

如果我經歷過每一次查看你說的方式,它的工作原理(這就是我所做的)。所以我只是想知道,如果這是一個爲我工作的功能,或者我必須自己做。 – Alesqui

回答

3

我認爲你可以把佈局看作一棵樹。因此,您只需要對根節點的引用。如果您將其移除,則會將其與孩子一起收集起來,因爲沒有其他人會引用它們。

如果由於某種原因,您在此操作後仍然可以看到一些視圖,則表示它們屬於不同的節點。您可以隨時使用層次瀏覽器「看到」您的UI更好:http://developer.android.com/guide/developing/debugging/debugging-ui.html

+0

我認爲這樣做可行,但我不確定是刪除根目錄還是通過每個視圖並刪除它們。也許這種或那種方式有一些竅門。但是由於似乎沒有,所以你的答案是:D – Alesqui

0

它不是一個遞歸的例子,但我認爲,它可以解決你的問題:

public void ClearRelLayout(RelativeLayout RL){ 
    for(int x=0;x<RL.getChildCount();x++){ 
     if(RL.getChildAt(x) instanceof FrameLayout){ 
      FrameLayout FL = (FrameLayout) RL.getChildAt(x); 
      FL.removeAllViewsInLayout(); 
     } 
    } 
    RL.removeAllViewsInLayout(); 
} 

而不是使用遞歸,只是循環通過每個孩子,並清除它,如果它是一個FrameLayout

+0

它不應該從後者調用'removeAllViews()'而不是'removeAllViewsInLayout()'JavaDoc「不要調用這個方法,除非你擴展了ViewGroup並且理解了查看測量和佈局管線「。 – osundblad

+1

我認爲你可以做得更好,而不是檢查'instanceof FrameLayout',你可以檢查'instanceof ViewGroup'。你會看到其他的佈局('LinearLayout','GridLayout'等) –

0

首先,通常你應該打電話removeAllViews()而不是removeAllViewsInLayout()閱讀JavaDoc的差異。

這些函數都不是遞歸的,它們只是從它所調用的對象中移除視圖。子結構不會改變。這可能會導致問題甚至內存泄漏,如果它們引用了保存的其他對象。

例如,如果您有以下結構:

<LinearLayout id='top'> 
     <LinearLayout id='sub'> 
     <Button id='b'/> 
     </LinearLayout> 
    </LinearLayout> 

top調用removeAllViews()佈局sub仍然指向b(和b將把sub父)。這意味着您不能在其他位置重新使用b,而無需先將其移除(sub)。如果你這樣做,你會得到一個例外。

+0

但是佈局'sub'和所有的孩子都被垃圾收集了嗎?我一直在試圖找到答案,我希望是的,因爲沒有別的東西會引用'sub'。 –

+0

它應該是因爲它們沒有外部引用,但我不知道(寫得很糟糕的gc可能會離開它們,或者可能還有其他一些Android的隱藏引用) – osundblad