2013-02-10 21 views
8

Właśnie napisałem odpowiedź dla kogoś zdezorientowanego przez findViewById i zdałem sobie sprawę, że mam lukę w moim zrozumieniu. To pytanie dotyczy tylko wiedzy i ciekawości.Jak findViewById zainicjować widok

Rozważ to:

button = (Button)findViewById(R.id.button); 

findViewById zwraca instancję View, który następnie oddanych do klasy docelowej. Jak dotąd wszystko dobrze.

Aby skonfigurować widok, findViewById tworzy AttributeSet z parametrów w powiązanej deklaracji XML, która przechodzi do konstruktora z View.

Następnie oddaliśmy instancję View do Button.

W jaki sposób AttributeSet przechodzi z kolei do konstruktora Button?

[EDIT]

Więc byłem zdezorientowany jeden :). Chodzi o to, że gdy układ jest zawyżony, hierarchia widoków zawiera już instancję klasy potomka widoku. findViewById po prostu zwraca referencję do niego. Oczywiste, kiedy o tym pomyślisz - doh ..

+0

+5 za zadanie ... z powodu Twojego pytania Przebadałem i znalazłem pełną informację dotyczącą bazy c flow .... dzięki @Leonidos – Pragnani

Odpowiedz

10

findViewById nic nie robi. Po prostu przegląda hierarchię widoku i zwraca odwołanie do widoku z żądanym viewId. View jest już utworzony i istnieje. Jeśli nie zadzwonisz pod numer findViewById, dla niektórych widoków nic się nie zmieni.

Widoki są zawyżone o LayoutInflator. Podczas wywoływania setContentView układ XML jest analizowany i tworzona jest hierarchia widoków.

Atrybuty przekazane do konstruktora Button przez LayoutInflater. sprawdź LayoutInflator source code.

+0

Ah, rozumiem. Masz na myśli, w widoku heirarchy, widok odniesienia jest już utworzony przez wywołanie ctor prawidłowej klasy potomka? – Simon

+0

Atrybuty przekazane do konstruktora Button przez pompowanie układu. sprawdź [Kod źródłowy LayoutInflarot] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/view/LayoutInflater.java#LayoutInflater. nadmuchać% 28org.xmlpull.v1.XmlPullParser% 2Candroid.view.ViewGroup% 2Cboolean% 29). – Leonidos

+0

Dziękuję Leonidos. – Simon

5

Nie sądzę, że findViewById() konstruuje lub tworzy instancje widoku. Będzie wyszukiwał w widoku hierarchii już zawyżonego układu, dla widoku z pasującym identyfikatorem. Ta metoda działa inaczej dla View i dla .

z Android Kod źródłowy:

View.findViewById() powraca ten sam widok obiektu, jeśli ten pogląd podanym identyfikatorze lub NULL, to nazywa:

protected View findViewTraversal(int id) { 
    if (id == mID) { 
     return this; 
    } 
    return null; 
} 

iteracji widoków podrzędnych i zwraca ten sam sposób na tych Widoki, to wywołanie:

protected View findViewTraversal(int id) { 
    if (id == mID) { 
     return this; 
    } 

    final View[] where = mChildren; 
    final int len = mChildrenCount; 

    for (int i = 0; i < len; i++) { 
     View v = where[i]; 

     if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { 
      v = v.findViewById(id); 

      if (v != null) { 
       return v; 
      } 
     } 
    } 

    return null; 
} 
+0

co to jest mide, kiedy szukam w widoku mId klasy jest przypisany do No_ID..Gdzie on przypisał mID do przemierzonego widoku id – Pragnani

+0

@Pagagnani 'mIDd jest przypisany identyfikator widoku. gdy Ty/inflator wywołasz 'setId (int id)' w widoku, 'mID' jest ustawiony na dostarczoną wartość int. –