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; }