2011-02-02 18 views

Odpowiedz

17

If you have all your Views in a LinearLayout lub inny container który rozciąga ViewGroup można korzystać z funkcji getChildCount() i getChildAt(int) i iterację wszystkich
zawarte widokami.

Mam nadzieję, że to pomoże.

+0

Tak, to działa idealnie. Dzięki! Musiałem nadpisać moje funkcje setContentView() w mojej podstawowej aktywności, aby móc przechowywać wskaźnik do głównej grupy ViewGroup, a następnie iterować ją za pomocą metody. – swinefeaster

+1

Alternatywnie do przesłonięcia setContentView, mógłbyś dostarczyć identyfikator do zewnętrznego kontenera w nadpisanym widoku, a następnie chwycić go za pomocą findViewById(). –

1

Aktywność Zasadniczo zawiera jeden główny pojemnik układu, w którym znajdują się wszystkie inne widoki. Korzystanie z odniesienia głównego kontenera układu. Przechodzenie przez swoje dziecko (Use getChild (postion), getchildcount() itp.). a jeśli jakieś dziecko jest samym kontenerem, zastosuj na nim tę samą funkcję. To jest trochę jak przechodzenie przez strukturę drzewa.

0

Jeśli rzeczywiście potrzebujesz iteratora, w api nie ma nic podobnego. Musisz napisać własną, która jest zbudowana na logice, którą sugerują Harry Joy i Javanator.

7

Zakładając, że według "wszystkich widoków w Twojej Działalności" masz na myśli każdy widok w hierarchii, nie ma takiego Iterator ani niczego w Androidzie, który pozwala ci na iterację po wszystkich widokach.

ViewGroup s mają metody getChildCount i getChildAt, ale dotyczą one bezpośrednich dzieci z ViewGroup. Musisz więc odwiedzić każde dziecko i sprawdzić, czy to jest samo w sobie ViewGroup i tak dalej. Krótko mówiąc, chciałem taką funkcję znaleźć wszystkie widoki pasujące do konkretnego tagu (findViewWithTag zwraca tylko pierwszy), więc napisałem a few classes, aby to osiągnąć. Oto w jaki sposób można iteracyjne nad każdym zdaniem pod Layout:

LayoutTraverser.build(new LayoutTraverser.Processor() { 
    @Override 
    public void process(View view) { 
    // do stuff with the view 
    } 
}).traverse(viewGroup); 
+0

Link do strony autora z kodem źródłowym dla tej klasy: http://android-wtf.com/2013/06/how-to-easily-traverse-any-view-hierarchy-in-android/ – ruX

1

Oto mój przykład, na podstawie Harry Joy's answer. To iteracje przez wszystkie hierarchie dominującej ViewGroup aby sprawdzić, czy któryś z widokiem nigdzie w nim są Button:

private boolean doesViewGroupContainButton(ViewGroup parentView) { 

     int numChildViews = parentView.getChildCount(); 
     for (int i = 0; i < numChildViews; i++) { 
      View childView = parentView.getChildAt(i); 
      if (childView instanceof ViewGroup) { 
       if (doesViewContainButton((ViewGroup)childView)) { 
        return true; 
       } 
      } 
      else if (childView instanceof Button) { 
       return true; 
      } 
     } 
     return false; 

    } 
0

Jeśli chcesz uniknąć brzydkie for (int i = 0; ....) można użyć statycznej wrapper

public class Tools 
{ 
    public static Iterable<View> getChildViews(final ViewGroup view) 
    { 
     return new Iterable<View>() 
     { 
      int i = -1; 

      @NonNull 
      @Override 
      public Iterator<View> iterator() 
      { 
       return new Iterator<View>() 
       { 
        int i = -1; 
        @Override 
        public boolean hasNext() 
        { 
         return i < view.getChildCount(); 
        } 

        @Override 
        public View next() 
        { 
         return view.getChildAt(++i); 
        } 
       }; 
      } 

     }; 
    } 
} 

i używać go jak tak

for (View view : Tools.getChildViews(viewGroup)) 

oczywiście jest to nieco mniej wydajny, ponieważ jesteś creat nowego obiektu, który można powtórzyć za każdym razem, gdy będziesz go sprawdzać, ale możesz go rozbudować, jeśli chcesz.

Powiązane problemy