2011-08-10 15 views
6

Czy istnieje sposób na usunięcie rekurencyjnie widoków z układu? Wydaje się, że funkcja removeAllViewsInLayout() nie wykonuje tego zadania (usuwa wszystkie widoki z układu, ale nie widoki podrzędne układu). W moim programie dodam niektóre FrameLayouts dynamicznie przez RelativeLayout, a nad tymi FrameLayouts dodam niektóre ImageViews i TextViews. Więc chcę wiedzieć, czy będę musiał zrobić własny kod rekurencyjny, usuwając kod widoku, czy też jest dostępny.Android - usuwa widoki w układzie rekurencyjnie

+0

Czy próbowałeś po prostu usunąć FrameLayouts zamiast TextViews/ImageViews, a następnie powrócić do FrameLayout? – Rob

+0

Jeśli przejdę przez każdy widok tak, jak mówisz, działa (i to właśnie robię). Chciałem tylko wiedzieć, czy to funkcja, która wykonuje to zadanie dla mnie, czy też muszę to zrobić sam. – Alesqui

Odpowiedz

3

Myślę, że można uznać układ za drzewo. Dlatego potrzebujesz tylko odniesienia do węzła głównego. Jeśli go usuniesz, zostanie on zebrany wraz z jego dziećmi, ponieważ nic innego nie odwołuje się do nich.

Jeśli z jakiegoś powodu nadal widzisz niektóre widoki po tej operacji, oznacza to, że należały do ​​innego węzła. Zawsze można użyć Hierarchy Viewer „zobaczyć” Twój UI lepiej: http://developer.android.com/guide/developing/debugging/debugging-ui.html

+0

Myślałem, że to zadziała, ale nie byłem pewien, czy usunąć root, czy przejść przez każdy widok i je usunąć. Może był jakiś trik w taki czy inny sposób. Ale ponieważ wydaje się, że nie ma, twoja odpowiedź brzmi: D – Alesqui

0

To nie jest rekurencyjny przykład, ale wierzę, że można go rozwiązać swój problem:

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(); 
} 

zamiast używać rekurencji, tylko pętli każdego dziecka i wyczyścić go, jeśli jest to FrameLayout

+0

Nie powinien wywoływać 'removeAllViews()' zamiast 'removeAllViewsInLayout()' JavaDoc z tego ostatniego "Nie wywołuj tej metody, chyba że rozszerzasz ViewGroup i rozumiesz zobacz pipeline pomiarowy i układowy. " – osundblad

+1

Myślę, że możesz zrobić jeden lepszy i zamiast sprawdzać 'instanceof FrameLayout', możesz sprawdzić' instanceof ViewGroup'. Złapiesz inne układy ('LinearLayout',' GridLayout', itp.) –

0

po pierwsze, zazwyczaj należy zadzwonić removeAllViews() zamiast removeAllViewsInLayout() przeczytać javaDoc dla różnicy.

Również żadna z tych funkcji nie jest rekurencyjna, jedynie usuwa widoki z obiektu, do którego jest wywoływana. Podstruktury się nie zmienią. Może to powodować problemy, a nawet wycieki pamięci, jeśli mają odniesienia do innych obiektów, które są przechowywane.

Na przykład jeśli mają następującą strukturę:

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

i nazywają removeAllViews() na top układ sub będzie nadal odnoszą b (i b skieruje sub jako rodzica). Oznacza to, że nie można ponownie użyć numeru b w innym miejscu bez uprzedniego usunięcia go nadrzędnego (sub). Jeśli to zrobisz, otrzymasz wyjątek.

+0

Ale czy układ "sub" i wszystkie jego dzieci będą zbierane ze śmieci? Próbowałem znaleźć odpowiedź na to i mam nadzieję, że tak, ponieważ nic innego nie będzie odwoływać się do "sub". –

+0

Powinny, ponieważ nie mają zewnętrznych odniesień, ale nie wiem, że (źle napisane gc może je opuścić, lub może jest jakieś inne ukryte odniesienie przez Androida) – osundblad

Powiązane problemy