Lorsqu'un élément Activity
est sélectionné, il est invité à dessiner sa mise en page.
Le framework Android gère la procédure de dessin, mais l'élément Activity
doit fournir le nœud racine de sa hiérarchie de mise en page.
Le dessin commence par le nœud racine de la mise en page. L'arborescence de mise en page doit être mesurée et dessinée. Le dessin est géré en parcourant l'arborescence et en affichant chaque View
qui croise la région incorrecte. Chaque ViewGroup
est responsable de la demande de dessin de chacun de ses enfants (avec la méthode draw()
), et chaque View
est responsable du dessin lui-même.
Comme l'arborescence est balayée dans le sens inverse, les parents sont dessinés avant (ou derrière) leurs enfants, et les frères dans l'ordre dans lequel ils apparaissent dans l'arborescence.
Remarque : Le framework ne dessine pas d'objets View
qui ne se trouvent pas dans une région valide. Il se charge également de dessiner l'arrière-plan View
pour vous.
Vous pouvez forcer le dessin d'un élément View
en appelant invalidate()
.
Le tracé de la mise en page s'effectue en deux étapes : une étape de mesure et une autre de mise en page.
Étape de mesure
La mesure est implémentée dans measure(int, int)
et effectue un balayage de haut en bas de l'arborescence View
. Chaque View
transmet les spécifications de dimension vers le bas de l'arborescence pendant la récursion. À la fin de la mesure, chaque View
a stocké ses mesures. La deuxième étape a lieu dans layout(int, int, int, int)
et s'effectue également de haut en bas. Au cours de cette opération, chaque parent est responsable du positionnement de tous ses enfants à l'aide des tailles calculées dans l'étape de mesure.
Lorsque la méthode measure()
d'un objet View
est renvoyée, ses valeurs getMeasuredWidth()
et getMeasuredHeight()
doivent être définies, ainsi que celles qui correspondent à tous les descendants de cet objet View
.
Les valeurs de largeur et de hauteur mesurées d'un objet View
doivent respecter les contraintes imposées par les parents de l'objet View
. Cette approche garantit qu'à la fin de la mesure, tous les parents accepteront toutes les mesures de leurs enfants. Un parent View
peut appeler measure()
plusieurs fois pour ses enfants. Par exemple, le parent peut mesurer une fois chaque enfant avec des dimensions non spécifiées pour déterminer la taille qu'ils veulent avoir, puis appeler measure()
pour les mesurer à nouveau avec des nombres réels si la somme de toutes les tailles non limitées des enfants est trop élevée ou trop faible (autrement dit, si les enfants ne parviennent pas à se mettre d'accord sur l'espace qu'ils occuperont chacun, le parent intervient et prend cette décision pour eux lors de deuxième étape).
La mesure utilise deux classes pour communiquer les dimensions. La classe ViewGroup.LayoutParams
est utilisée par les objets View
pour indiquer à leur parent comment ils souhaitent mesurer et positionner leurs données. La classe ViewGroup.LayoutParams
de base décrit simplement la largeur et la hauteur souhaitées par l'élément View
. Pour chaque dimension, elle peut spécifier l'une des valeurs suivantes :
- Un nombre exact
MATCH_PARENT
, ce qui signifie queView
veut être aussi grand que son parent (moins la marge intérieure)WRAP_CONTENT
, ce qui signifie queView
veut avoir la taille minimale suffisante pour accueillir son contenu (plus une marge intérieure)
Il existe des sous-classes de ViewGroup.LayoutParams
pour différentes sous-classes de ViewGroup
.
Par exemple, RelativeLayout
possède sa propre sous-classe de ViewGroup.LayoutParams
, qui permet de centrer les objets enfants View
horizontalement et verticalement.
Les objets MeasureSpec
sont utilisés pour transmettre les exigences vers le bas de l'arborescence, du parent à l'enfant. Un élément MeasureSpec
peut avoir l'un des trois modes suivants :
UNSPECIFIED
: permet à un parent de déterminer la dimension souhaitée d'un élémentView
enfant. Par exemple, un élémentLinearLayout
peut appelermeasure()
pour son enfant avec la hauteur définie surUNSPECIFIED
et une largeur de 240 "EXACTLY
" pour déterminer la taille que l'élémentView
enfant souhaite avoir pour une largeur de 240 pixels.EXACTLY
: valeur utilisée par le parent pour imposer une taille exacte à l'élément enfant. L'enfant doit utiliser cette taille et s'assurer que tous ses descendants s'adaptent à cette taille.AT MOST
: valeur utilisée par le parent pour imposer une taille maximale à l'enfant. L'enfant doit s'assurer que tous ses descendants et lui-même respectent cette taille.
Étape de mise en page
Pour initier une mise en page, appelez requestLayout()
.
Cette méthode est généralement appelée par un élément View
qui estime qu'il ne peut plus tenir dans ses limites actuelles.