Cómo findViewById inicializa una vista

Acabo de escribir una respuesta para alguien confundido por findViewById y me di cuenta de que tengo una brecha en mi comprensión. Esta pregunta es sólo para el conocimiento y la curiosidad.

Considera esto:

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

findViewById devuelve una instancia de View , que se findViewById a la clase de destino. Todo bien hasta ahora.

Para configurar la vista, findViewById construye un AttributeSet partir de los parámetros de la declaración XML asociada que pasa al constructor de View .

A continuación, emitimos la instancia de View en Button .

¿Cómo se pasa el AttributeSet a su vez al constructor Button ?

[EDITAR]

Así que yo estaba confundido :). Todo el punto es que cuando el diseño está inflado, la jerarquía de vista ya contiene una instancia de la clase descendente de vista. FindViewById simplemente devuelve una referencia a ella. Obvio cuando lo piensas – doh ..

findViewById no hace nada. Sólo mira a través de la jerarquía de la vista y devuelve la referencia a una vista con viewId solicitado. View ya está creada y existe. Si no llama a findViewById para alguna vista, nada cambia.

Las vistas son infladas por LayoutInflator . Cuando se llama a setContentView xml se analiza el diseño y se crea la jerarquía de vista.

Atributos pasados ​​al constructor de Button por LayoutInflater . Compruebe el código fuente de LayoutInflator .

No creo que findViewById() construye o instancia una vista. Se buscará en la jerarquía Vista de diseño ya inflado, para una vista con id de coincidencia. Este método funciona de forma diferente para una View y para un grupo de ViewGroup .

Desde Android Código fuente:

View.findViewById() devuelve el mismo objeto View si esta vista tiene el id dado o null, llama a:

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

ViewGroup.findViewById() itera a través de vistas secundarias y llama al mismo método en estas vistas, llama:

  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; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.