2010-05-19 5 views
11

J'ai une disposition qui spécifie la taille des widgets en dimension par rapport, par exemple:Comment obtenir la taille d'un widget Android après le calcul de la mise en page?

<LinearLayout ... layout_height="fill_parent"> 
    <ImageView ... layout_height="wrap_content" /> 
    <TextView ... layout_height="120dp" /> 
</LinearLayout> 

Immédiatement après onCreate, je veux savoir combien est la hauteur du ImageView. Comment faire ça?

Note: Si j'appelle getHeight() à onCreate, je reçois 0.

J'ai aussi essayé imageView.postDelayed, cela fonctionne sur 2.1 émulateur mais échoue sur 1,5 émulateur (je suis arrivé à 0, aussi).

Enfin, j'ai essayé de créer un Handler, puis j'appelle handler.postDelayed avec un délai de 10 ms. Il fonctionne à la fois dans l'émulateur 2.1 et 1.5, mais échoue quand je lance le programme dans le débogueur eclipse (Donc, je conclus que l'utilisation du retard ne garantit pas que l'obtention de la hauteur survienne après la mise en page.)

Répondre

11

La raison pour laquelle vous obtenez une taille de 0 est que la mise en page n'est pas terminée tant que l'activité n'est pas entièrement créée, c.-à-d. OnCreate(), onStart() et onResume(). Le moyen le plus simple que je connaisse pour obtenir la taille exacte est d'appeler votre méthode une fois la mise en page terminée, par exemple en utilisant un écouteur de clic sur un bouton. Comme le bouton n'est pas affiché tant que la mise en page n'est pas terminée, la taille doit être disponible au moment où son écouteur de clic est déclenché. Ceci n'est qu'une conjecture, mais j'imagine que c'est difficile à faire précisément parce qu'ils ne veulent pas que les gens jouent avec des tailles de mise en page une fois que le système vient de terminer l'affichage de l'écran. S'ils fournissaient un rappel "onLayoutFinished()", alors vous pourriez vous coincer dans une boucle si vous avez modifié la disposition dans cela. Par exemple, imaginez: la mise en page est terminée; onLayoutFinished() appelé et vous modifiez la mise en page là-bas; la disposition existante est maintenant invalide; mise en page refaite; onLayoutFinished() appelé à nouveau; votre code est appelé à nouveau - et ainsi de suite.

Une autre méthode consiste à créer une vue personnalisée et à remplacer la méthode onMeasure(int, int). Le système déclenche cette méthode pour obtenir la taille de chaque vue; si vous utilisez quelque chose comme mon exemple ci-dessous, vous pouvez obtenir le suggéré la taille avant la mise en page est terminée:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    //getMeasuredHeight() and getMeasuredWidth() now contain the suggested size 
} 

(je l'ai écrit que c'est la taille suggérée parce que je pense qu'il est possible de la taille à changer après Ceci est basé sur des contraintes de disposition, mais c'est un vague souvenir de quelque chose que j'ai lu il y a un moment, et je n'ai jamais expérimenté en détail.) Une fois que vous avez fait cela, vous pouvez utiliser la taille pour tout ce que vous voulez faire. peut même changer la taille qu'il utilisera en utilisant setMeasuredDimension(newX, newY).

+0

Merci beaucoup. Ça sonne le chemin. Je vais essayer ça. – yuku

+2

Ceci est une grande contrainte à mon humble avis. Ne pas pouvoir obtenir des mesures sans passer outre une vue ou une mise en page ou ajouter un bouton dont vous n'avez pas vraiment besoin. –

7

L'objet View fournit une méthode appelée onSizeChanged (int w, int h, int oldw, int oldh). Il est appelé lorsque la mise en page change la taille de l'un de ses composants. Si vous remplacez cette méthode, le code de votre version de cette méthode connaîtra la taille de lui-même, comme indiqué dans l'extrait suivant.

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    bounds = new Rect(); 
    this.getDrawingRect(bounds); 
    // bounds will now contain none zero values 
} 
Questions connexes