2013-02-10 11 views
8

Ho appena scritto una risposta per qualcuno confuso da findViewById e ho capito che ho una lacuna nella mia comprensione. Questa domanda è solo per conoscenza e curiosità.In che modo findViewById inizializza una vista

Considerate questo:

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

findViewById restituisce un'istanza di View, che viene poi gettato alla classe di destinazione. Tutto bene finora.

Per impostare la vista, findViewById costruisce un AttributeSet dai parametri della dichiarazione XML associata che passa al costruttore di View.

Quindi inoltrare l'istanza View a Button.

In che modo il AttributeSet viene passato a turno al costruttore Button?

[EDIT]

quindi ero confuso uno :). Il punto è che quando il layout è gonfiato, la gerarchia della vista contiene già un'istanza della classe discendente della vista. findViewById restituisce semplicemente un riferimento ad esso. Ovvio quando ci pensate - doh ..

+0

+5 per la ricerca .... a causa della tua domanda ho ricercato e trovare le informazioni complete relative alla base c flusso .... grazie a @Leonidos – Pragnani

risposta

10

findViewById non fa nulla. Osserva semplicemente la gerarchia delle viste e restituisce il riferimento a una vista con viewId richiesto. View è già stato creato ed esiste. Se non chiami findViewById per qualche vista, nulla cambia.

Le viste sono gonfiate da LayoutInflator. Quando chiami il layout setContentView xml viene analizzato e viene creata la gerarchia di visualizzazione.

attributi passati al costruttore di Button da LayoutInflater. controllare LayoutInflator source code.

+0

Ah, ho capito. Vuoi dire nella vista dell'erarchia, la vista di riferimento è già istanziata chiamando il ctor della classe discendente corretta? – Simon

+0

attributi passati al costruttore di Button per influsso di layout. controllare [LayoutInflarot codice sorgente] (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/view/LayoutInflater.java#LayoutInflater. gonfiare% 28org.xmlpull.v1.XmlPullParser% 2Candroid.view.ViewGroup% 2Cboolean% 29). – Leonidos

+0

Grazie Leonidos. – Simon

5

Non credo che findViewById() costruisca o instanzia una vista. Cerca nella gerarchia View di un layout già gonfiato, per una vista con id corrispondente. Questo metodo funziona in modo diverso per un e per un ViewGroup.

da Android Codice sorgente:

View.findViewById() restituisce lo stesso oggetto View se questo punto di vista ha l'id o nulla dato, si chiede:

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

scorre vista minorile e chiede lo stesso metodo su questi Visualizzazioni, chiamate:

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

cos'è mId, quando cerco nella vista la classe mId è assegnata a No_ID..where ha assegnato mId all'ID di vista attraversata – Pragnani

+0

@Pragnani 'mId' è l'ID assegnato alla vista. quando tu/inflater chiami 'setId (int id)' su una vista, 'mID' è impostato sul valore int fornito. –

Problemi correlati