2012-12-14 13 views
12

Ok, więc mam xml układ podobny do następującego przykładu:Android: Jak znaleźć widoki według typu

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:background="@drawable/tile_bg" > 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:paddingTop="10dp" > 

    <LinearLayout 
     android:id="@+id/layout_0" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- view stuff here --> 
    </LinearLayout> 

    <!-- more linear layouts as siblings to this one --> 

</LinearLayout> 

I rzeczywiście mają około przedmioty 7 LinearLayout każdy z id rosnącym od layout_0 etc. Chcę mieć możliwość zdobycia wszystkich elementów LinearLayout w katalogu głównym LinearLayout. Czy muszę podać identyfikator na głównym i znaleźć wszystkie inne przez id lub czy mogę uzyskać je według typu.

Kod używam napompować układ jest:

Czytałem gdzieś, że można iteracyjne dzieci o ViewGroup ale to tylko widok.

Jaki jest najlepszy sposób na uzyskanie grupy dzieci według typu?

Odpowiedz

24

To powinno Cię doprowadzić na właściwą drogę.

LinearLayout rootLinearLayout = (LinearLayout) findViewById(R.id.rootLinearLayout); 
int count = rootLinearLayout.getChildCount(); 
for (int i = 0; i < count; i++) { 
    View v = rootLinearLayout.getChildAt(i); 
    if (v instanceof LinearLayout) { 
     ... 
    } 
} 
+1

Powinny być Andres

+0

Uważaj, aby 'instanceof' był ciężką operacją. Ta Aproach może być powolna w widoku z mnóstwem połączeń chlidren –

+0

@EmrysMyrooin Kosztowne są tylko problemem, jeśli powodują opóźnienia między danymi wejściowymi. Jeśli jest to po prostu inicjalizacja w metodzie onCreate, to nie powinno to w ogóle zaszkodzić, ponieważ użytkownik i tak nie miał okazji nic zrobić. Powiedziawszy to, nie ma żadnej realnej potrzeby, jeśli jest ich tylko 7. W tym przypadku nadal potrzebna byłaby optymalizacja. Pętla jest wystarczająco droga, zawieszając pętlę UI. –

1

Należy dodać identyfikator do korzenia LinearLayout:

<LinearLayout 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    android:paddingTop="10dp" > 

    <LinearLayout 
     android:id="@+id/layout_0" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <!-- view stuff here --> 
    </LinearLayout> 

    <!-- more linear layouts as siblings to this one --> 

</LinearLayout> 

Następnie napompowania całego układu jak zwykle:

się trzymać na korzeniu LinearLayout:

LinearLayout root = (LinearLayout) view.findViewById(R.id.root); 

LinearLayout[] children = new LinearLayout[root.getChildCount()]; 

for (int i = 0; i < root.getChildCount(); i++) { 
    children[i] = (LinearLayout) root.getChildAt(i); 
} 
1

Przepuścić root vie w jako argument tej metody DFS:

private List<LinearLayout> mArr = new ArrayList<LinearLayout>(); 

private void getLinearLayouts(ViewGroup parent) { 
    int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     View child = parent.getChildAt(i); 
     if (child instanceof ViewGroup) { 
      getLinearLayouts((ViewGroup) child); 
      if (child instanceof LinearLayout) 
       mArr.add((LinearLayout) child); 
     } 
    } 
} 
3

można bezpiecznie oddać swój pogląd wynik do ViewGroup jeśli wiesz, że element główny układ jest dowolny podklasa jak LinearLayout lub innych układów:

ViewGroup vg = (ViewGroup)view; 

i używaj, jak chcesz. Jeśli wiesz, że będziesz zawsze stosowanie tylko jednego typu układu do pojemnika głównego, można rzucić do tego typu, tj:

LinearLayout vg = (LinearLayout)view; 
1

Chciałem tylko dodać więcej rodzajowe jeden, ale trzeba zachować biorąc pod uwagę, że jest to ciężkie podejście do tego.

W każdym razie, oto kod:

private static <T extends View> ArrayList<T> getChildrenOfParentWithClass(ViewGroup parent, Class<T> clazz) 
{ 
    ArrayList<T> children = new ArrayList<>(); 

    int childCount = parent.getChildCount(); 
    for (int i = 0; i < childCount; i++) 
    { 
     View child = parent.getChildAt(i); 
     if (child instanceof ViewGroup) 
     { 
      children.addAll(getChildrenOfParentWithClass((ViewGroup) child, clazz)); 
      if (child.getClass().equals(clazz)) 
      { 
       children.add((T) child); 
      } 
     } 
    } 

    return children; 
} 
+0

Musisz wstawić drugi blok 'if', z pierwszego bloku' if'! –

0

jak na @ ChristopheCVB odpowiedź, ale również obsługuje dziedziczenie (Patrz tClass.isInstance(child)).

public static <T extends View> ArrayList<T> getViewsByType(ViewGroup root, Class<T> tClass) { 
    final ArrayList<T> result = new ArrayList<>(); 
    int childCount = root.getChildCount(); 
    for (int i = 0; i < childCount; i++) { 
     final View child = root.getChildAt(i); 
     if (child instanceof ViewGroup) 
      result.addAll(getViewsByType((ViewGroup) child, tClass)); 

     if (tClass.isInstance(child)) 
      result.add(tClass.cast(child)); 
    } 
    return result; 
} 

I prosty przykład użycia:

ArrayList<TextView> TextViews = getViewsByType(rootLayout, TextView.class); 

Thank akceptowane odpowiedź.

Powiązane problemy