onMeasure()
est votre occasion de dire à Android la taille que vous souhaitez que votre vue personnalisée dépende des contraintes de mise en page fournies par le parent; c'est également l'occasion pour votre vue personnalisée d'apprendre quelles sont ces contraintes de disposition (au cas où vous voudriez vous comporter différemment dans une match_parent
situation que dans une wrap_content
situation). Ces contraintes sont regroupées dans les MeasureSpec
valeurs transmises à la méthode. Voici une corrélation approximative des valeurs de mode:
- EXACTEMENT signifie que la valeur
layout_width
ou a layout_height
été définie sur une valeur spécifique. Vous devriez probablement faire votre point de vue de cette taille. Cela peut également être déclenché lorsque match_parent
est utilisé, pour définir la taille exactement à la vue parent (cela dépend de la disposition dans le cadre).
- AT_MOST signifie généralement que la valeur
layout_width
ou a layout_height
été définie sur match_parent
ou wrap_content
là où une taille maximale est nécessaire (cela dépend de la disposition dans le cadre), et la taille de la dimension parent est la valeur. Vous ne devriez pas être plus grand que cette taille.
- NON SPÉCIFIÉ signifie généralement que la valeur
layout_width
ou a layout_height
été définie sur wrap_content
sans aucune restriction. Vous pouvez avoir la taille que vous souhaitez. Certaines dispositions utilisent également ce rappel pour déterminer la taille souhaitée avant de déterminer les spécifications pour vous transmettre à nouveau dans une deuxième demande de mesure.
Le contrat qui existe avec onMeasure()
est - ce que setMeasuredDimension()
DOIT être appelée à la fin de la taille que vous souhaitez que la vue soit. Cette méthode est appelée par toutes les implémentations du framework, y compris l'implémentation par défaut trouvée dans View
, c'est pourquoi il est sûr d'appeler à la super
place si cela correspond à votre cas d'utilisation.
Certes, car le cadre applique une implémentation par défaut, il peut ne pas être nécessaire pour vous de remplacer cette méthode, mais vous pouvez voir un écrêtage dans les cas où l'espace d'affichage est plus petit que votre contenu si vous ne le faites pas et si vous disposez votre vue personnalisée avec wrap_content
dans les deux sens, votre vue peut ne pas apparaître du tout car le framework ne sait pas quelle est sa taille!
Généralement, si vous remplacez View
et pas un autre widget existant, c'est probablement une bonne idée de fournir une implémentation, même si c'est aussi simple que quelque chose comme ceci:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
J'espère que cela pourra aider.