Quelle est la bonne façon de remplacer onMeasure ()? J'ai vu différentes approches. Par exemple, Professional Android Development utilise MeasureSpec pour calculer les dimensions, puis se termine par un appel à setMeasuredDimension (). Par exemple:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
}
D'autre part, selon cet article , la manière «correcte» est d'utiliser MeasureSpec, d'appeler setMeasuredDimensions (), suivi d' un appel à setLayoutParams () et de se terminer par un appel à super.onMeasure (). Par exemple:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Alors, quelle est la bonne manière? Aucune des deux approches n'a fonctionné à 100% pour moi.
Je suppose que ce que je demande vraiment, c'est que quelqu'un connaît un tutoriel qui explique onMeasure (), la mise en page, les dimensions des vues enfants, etc.?
android
android-layout
U Avalos
la source
la source
Réponses:
Les autres solutions ne sont pas globales. Ils peuvent fonctionner dans certains cas et sont un bon point de départ, mais ils ne sont pas garantis de fonctionner.
Lorsque onMeasure est appelé, vous pouvez ou non avoir le droit de modifier la taille. Les valeurs transmises à votre onMeasure (
widthMeasureSpec
,heightMeasureSpec
) contiennent des informations sur ce que votre vue enfant est autorisée à faire. Actuellement, il existe trois valeurs:MeasureSpec.UNSPECIFIED
- Vous pouvez être aussi grand que vous le souhaitezMeasureSpec.AT_MOST
- Aussi grand que vous le souhaitez (jusqu'à la taille des spécifications), c'estparentWidth
dans votre exemple.MeasureSpec.EXACTLY
- Pas le choix. Parent a choisi.Ceci est fait pour qu'Android puisse effectuer plusieurs passes pour trouver la bonne taille pour chaque élément, voir ici pour plus de détails.
Si vous ne suivez pas ces règles, votre approche n'est pas garantie de fonctionner.
Par exemple, si vous souhaitez vérifier si vous êtes autorisé à modifier la taille, vous pouvez effectuer les opérations suivantes:
En utilisant ces informations, vous saurez si vous pouvez modifier les valeurs comme dans votre code. Ou si vous devez faire quelque chose de différent. Un moyen rapide et facile de déterminer la taille souhaitée consiste à utiliser l'une des méthodes suivantes:
int resolutionSizeAndState (taille int, valeur int measureSpec, int childMeasuredState)
int resolutionSize (taille int, int measureSpec)
Alors que le premier n'est disponible que sur Honeycomb, le second est disponible sur toutes les versions.
Remarque: vous pouvez trouver cela
resizeWidth
ouresizeHeight
être toujours faux. J'ai trouvé que c'était le cas si je demandaisMATCH_PARENT
. J'ai pu résoudre ce problème en demandantWRAP_CONTENT
sur ma mise en page parent puis pendant la phase NON SPÉCIFIÉE en demandant une taille deInteger.MAX_VALUE
. Cela vous donne la taille maximale que votre parent autorise lors du prochain passage sur onMeasure.la source
La documentation fait autorité en la matière: http://developer.android.com/guide/topics/ui/how-android-draws.html et http://developer.android.com/guide/topics/ui/custom -components.html
Pour résumer: à la fin de votre
onMeasure
méthode surchargée , vous devez appelersetMeasuredDimension
.Vous ne devriez pas appeler
super.onMeasure
après avoir appelésetMeasuredDimension
, cela effacera simplement tout ce que vous avez défini. Dans certaines situations, vous souhaiterez peut-être appeler lesuper.onMeasure
premier, puis modifier les résultats en appelantsetMeasuredDimension
.Ne pas appeler
setLayoutParams
àonMeasure
. La mise en page se produit dans un deuxième passage après la mesure.la source
Je pense que cela dépend du parent de ce que vous dépassez.
Par exemple, si vous étendez un ViewGroup (comme FrameLayout), lorsque vous avez mesuré la taille, vous devez appeler comme ci-dessous
parce que vous voudrez peut-être à ViewGroup pour faire un travail de repos (faire quelques trucs sur la vue enfant)
Si vous étendez une vue (comme ImageView), vous pouvez simplement appeler
this.setMeasuredDimension(width, height);
, car la classe parente fera simplement quelque chose comme vous l'avez fait habituellement.En un mot, si vous voulez certaines fonctionnalités que votre classe parent offre gratuitement, vous devez appeler
super.onMeasure()
(passez généralement la spécification de mesure du mode MeasureSpec.EXACTLY), sinon l'appelthis.setMeasuredDimension(width, height);
suffit.la source
voici comment j'ai résolu le problème:
}
De plus, il était nécessaire pour le composant ViewPager
la source
super.onMeasure
effacera les dimensions définies à l'aide desetMeasuredDimension
.Si vous changez la taille des vues à l'intérieur de
onMeasure
tout ce dont vous avez besoin est l'setMeasuredDimension
appel. Si vous changez la taille en dehors deonMeasure
vous devez appelersetLayoutParams
. Par exemple, changer la taille d'une vue de texte lorsque le texte est modifié.la source
Dépend du contrôle que vous utilisez. Les instructions de la documentation fonctionnent pour certains contrôles (TextView, Button, ...), mais pas pour d'autres (LinearLayout, ...). La façon qui a très bien fonctionné pour moi était d'appeler le super une fois que j'aurais terminé. Basé sur l'article dans le lien ci-dessous.
http://humptydevelopers.blogspot.in/2013/05/android-view-overriding-onmeasure.html
la source
Je suppose que setLayoutParams et recalculer les mesures est une solution de contournement pour redimensionner correctement les vues enfants, car cela se fait généralement dans onMeasure de la classe dérivée.
Cependant, cela fonctionne rarement correctement (pour une raison quelconque ...), il vaut mieux appeler measureChildren (lors de la dérivation d'un ViewGroup) ou essayer quelque chose de similaire si nécessaire.
la source
vous pouvez prendre ce morceau de code comme exemple de onMeasure () ::
la source