2011-08-10 22 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