Cuando una Activity
recibe el foco, se le solicitará que dibuje su diseño.
El framework de Android manejará el procedimiento para dibujar, pero la Activity
debe proporcionar el nodo raíz de su jerarquía de diseño.
El dibujo comienza con el nodo raíz del diseño. Se solicita que mida y dibuje el árbol de diseño. El dibujo se maneja recorriendo el árbol y representando cada View
que se interseca con la región no válida. A su vez, cada ViewGroup
es responsable de solicitar que se dibuje cada uno de sus elementos secundarios (con el método draw()
), y cada View
es responsable de dibujarlo.
Debido a que el árbol se recorre por adelantado, los elementos superiores se dibujarán antes (es decir, detrás) de sus elementos secundarios, y los elementos de un mismo nivel se dibujarán en el orden en que aparezcan en el árbol.
Nota: El framework no dibujará objetos View
que no se encuentren en una región válida. También se encargará de dibujar el segundo plano de la View
por ti.
Puedes hacer que una View
dibuje llamando al invalidate()
.
Dibujar el diseño es un proceso de dos fases: una fase de medida y una de diseño.
Fase de medida
La fase de medida se implementa en measure(int, int)
y es un recorrido de arriba abajo del árbol View
. Cada View
empuja las especificaciones de dimensión hacia abajo en el árbol durante la recursión. Al final de la fase de medida, cada View
almacenó sus mediciones. La segunda fase ocurre en layout(int, int, int, int)
y también es de arriba abajo. Durante esa fase, cada elemento superior es responsable de ubicar todos sus elementos secundarios utilizando los tamaños procesados en la fase de medida.
Cuando se muestra el método measure()
de un objeto View
, se deben establecer los valores getMeasuredWidth()
y getMeasuredHeight()
, junto con los de todos los descendientes de ese objeto View
.
Los valores medidos de ancho y alto de un objeto View
deben respetar las restricciones impuestas por los elementos superiores del objeto View
. Eso garantiza que, al final de la fase de medida, todos los elementos superiores acepten todas las medidas de sus elementos secundarios. Un elemento superior View
puede llamar a measure()
más de una vez en sus elementos secundarios. Por ejemplo, el elemento superior puede medir cada elemento secundario una vez con dimensiones no especificadas para averiguar qué tan grande quiere ser y, luego, volver a llamar a measure()
con números reales si la suma de todos los tamaños sin restricciones es demasiado grande o demasiado pequeña (es decir, si los elementos secundarios no se ponen de acuerdo en cuanto al espacio que ocupan, el elemento superior intervendrá y establecerá las reglas en la segunda fase).
La fase de medida utiliza dos clases para comunicar dimensiones. La clase ViewGroup.LayoutParams
es utilizada por los objetos View
para decirles a sus elementos superiores cómo quieren ser medidos y posicionados. La clase ViewGroup.LayoutParams
base solo describe qué tan grande quiere ser View
en ancho y alto. Para cada dimensión, puede especificar una de las siguientes opciones:
- un número exacto
MATCH_PARENT
, lo que significa queView
quiere ser tan grande como su elemento superior (sin incluir el relleno)WRAP_CONTENT
, lo que significa queView
quiere ser lo suficientemente grande como para encerrar su contenido (más el relleno)
Hay subclases de ViewGroup.LayoutParams
para diferentes subclases de ViewGroup
.
Por ejemplo, RelativeLayout
tiene su propia subclase de ViewGroup.LayoutParams
, que incluye la capacidad de centrar objetos View
secundarios en sentido horizontal y vertical.
Los objetos MeasureSpec
se utilizan para empujar los requisitos hacia abajo del árbol, de elemento superior a elemento secundario. Una MeasureSpec
puede estar en uno de estos tres modos:
UNSPECIFIED
: Esto lo utiliza un elemento superior para determinar la dimensión deseada de unaView
secundaria. Por ejemplo, unLinearLayout
puede llamar ameasure()
en su elemento secundario con la altura establecida enUNSPECIFIED
y un ancho deEXACTLY
240 para averiguar qué tan alto quiere que ser laView
secundaria si el ancho es de 240 píxeles.EXACTLY
: El elemento superior lo usa para imponer un tamaño exacto al elemento secundario. El elemento secundario debe usar este tamaño y garantizar que todos sus descendientes se ajusten a este tamaño.AT MOST
: Esto lo usa el elemento superior para imponer un tamaño máximo al elemento secundario. El elemento secundario debe garantizar que él y todos sus descendientes se ajusten a este tamaño.
Fase de diseño
Para iniciar un diseño, llama a requestLayout()
.
Una View
suele llamar a este método para sí misma cuando cree que no puede seguir ajustándose a los límites actuales.