Comment puis-je dimensionner une vue en fonction de la taille de sa mise en page parent. Par exemple, j'ai un RelativeLayout
qui remplit le plein écran, et je veux qu'une vue enfant, disons an ImageView
, prenne toute la hauteur et 1/2 de la largeur?
J'ai essayé tout remplaçant sur onMeasure
, onLayout
, onSizeChanged
, etc et je ne pouvais pas le faire au travail ....
Réponses:
Je ne sais pas si quelqu'un lit encore ce fil ou non, mais la solution de Jeff ne vous mènera qu'à mi-chemin (un peu littéralement). Ce que son onMeasure va faire est d'afficher la moitié de l'image sur la moitié du parent. Le problème est que l'appel de super.onMeasure avant le
setMeasuredDimension
mesurera tous les enfants de la vue en fonction de la taille d'origine, puis coupera simplement la vue en deux lorsque lesetMeasuredDimension
redimensionnera.Au lieu de cela, vous devez appeler
setMeasuredDimension
(comme requis pour un remplacement onMeasure) et fournir un nouveauLayoutParams
pour votre vue, puis appelersuper.onMeasure
. N'oubliez pas que vousLayoutParams
êtes dérivé du type parent de votre vue, pas du type de votre vue.Je crois que la seule fois où vous aurez des problèmes avec le parent,
LayoutParams
c'est si le parent est unAbsoluteLayout
(ce qui est obsolète mais toujours utile).la source
MeasureSpec.getSize(widthMeasureSpec)
Donne- t-il vraiment la bonne largeur du parent? Pour moi, cela renvoie simplement des largeurs aléatoires qui sont assez proches de la largeur réelle, mais pas exactes.wrap_content
ne le fera pas. La réponse de Vic ne fonctionne pas pour ce scénario, contrairement au commentaire de @ M.Schenk. Il enregistre également une passe de mise en page supplémentaire. Vous devriez également le publier comme une réponse pour la visibilité.super.onMeasure()
simplement remplacer et annuler les effets de l'appel précédentthis.setMeasuredDimension()
?super.onMeasure()
ne remplace pas les calculs précédents.Vous pouvez résoudre ce problème en créant une vue personnalisée et en remplaçant la méthode onMeasure (). Si vous utilisez toujours "fill_parent" pour layout_width dans votre XML, le paramètre widthMeasureSpec qui est passé dans la méthode onMeasusre () doit contenir la largeur du parent.
Votre XML ressemblerait à ceci:
la source
J'ai trouvé qu'il était préférable de ne pas jouer avec le réglage vous-même des dimensions mesurées. Il y a en fait un peu de négociation entre les vues parent et enfant et vous ne voulez pas réécrire tout ce code .
Ce que vous pouvez faire, cependant, c'est modifier les measureSpecs, puis appeler super avec eux. Votre vue ne saura jamais qu'elle reçoit un message modifié de son parent et s'occupera de tout pour vous:
la source
Lorsque vous définissez une mise en page et une vue sur XML, vous pouvez spécifier la largeur et la hauteur de la mise en page d'une vue pour qu'elle soit un contenu enveloppant ou un parent de remplissage. Occuper la moitié de la zone est un peu plus difficile, mais si vous aviez quelque chose que vous vouliez sur l'autre moitié, vous pourriez faire quelque chose comme ce qui suit.
Donner le même poids à deux choses signifie qu'elles s'étireront pour occuper la même proportion de l'écran. Pour plus d'informations sur les mises en page, consultez la documentation des développeurs.
la source
Je pense que l' approche XML de Mayras peut être intéressante. Cependant, il est possible de le rendre plus précis, avec une seule vue en définissant le weightSum. Je n'appellerais plus cela un hack mais à mon avis l'approche la plus simple:
Comme ça, vous pouvez utiliser n'importe quel poids, 0,6 par exemple (et le centrage) est le poids que j'aime utiliser pour les boutons.
la source
Essaye ça
alors vous pouvez utiliser LinearLayout.LayoutParams pour définir les paramètres de chileView
la source
Vous pouvez maintenant utiliser PercentRelativeLayout. Boom! Problème résolu.
la source
Roman, si vous voulez faire votre mise en page en code Java (descendant de ViewGroup), c'est possible. L'astuce est que vous devez implémenter les méthodes onMeasure et onLayout. OnMeasure est appelé en premier et vous devez "mesurer" la sous-vue (en la dimensionnant effectivement à la valeur souhaitée). Vous devez le redimensionner lors de l'appel onLayout. Si vous ne parvenez pas à effectuer cette séquence ou à appeler setMeasuredDimension () à la fin de votre code onMeasure, vous n'obtiendrez pas de résultats. Pourquoi est-ce conçu de manière si compliquée et si fragile me dépasse.
la source
Si l'autre côté est vide. Je suppose que le moyen le plus simple serait d'ajouter une vue vide (par exemple une mise en page linéaire), puis de définir les largeurs des deux vues sur fill_parent et leurs deux poids sur 1.
Cela fonctionne dans un LinearLayout ...
la source
C'est quelque chose comme ça:
la source
Je me débat avec cette question depuis longtemps, je veux changer la largeur du tiroir de mon DrawerLayout, qui est le deuxième enfant de son parent. Récemment, je l'ai compris, mais je ne sais pas s'il y a une meilleure idée.
la source