Détermination de la taille d’une vue Android à l’exécution

J’essaie d’appliquer une animation à une vue de mon application Android après la création de mon activité. Pour ce faire, je dois déterminer la taille actuelle de la vue, puis configurer une animation à l’échelle de la taille actuelle à la nouvelle taille. Cette partie doit être effectuée au moment de l’exécution, car la vue s’adapte à différentes tailles en fonction des entrées de l’utilisateur. Ma mise en page est définie en XML.

Cela semble être une tâche facile, et il y a beaucoup de questions SO à ce sujet, mais aucune ne résout mon problème, évidemment. Alors peut-être que je manque quelque chose d’évident. Je reçois un aperçu de mon sharepoint vue en:

ImageView myView = (ImageView)getWindow().findViewById(R.id.MyViewID); 

Cela fonctionne bien, mais lorsque vous appelez getWidth() , getHeight() , getMeasuredWidth() , getLayoutParams().width , etc., ils renvoient tous 0. J’ai également essayé d’appeler manuellement measure() suivi d’un appel à getMeasuredWidth() , mais cela n’a aucun effet.

J’ai essayé d’appeler ces méthodes et d’inspecter l’object dans le débogueur dans mes activités onCreate() et onPostCreate() . Comment puis-je déterminer les dimensions exactes de cette vue à l’exécution?

Utilisez le ViewTreeObserver sur la vue pour attendre la première mise en page. Seulement après la première mise en page, getWidth () / getHeight () / getMeasuredWidth () / getMeasuredHeight () fonctionneront.

 ViewTreeObserver viewTreeObserver = view.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeOnGlobalLayoutListener(this); viewWidth = view.getWidth(); viewHeight = view.getHeight(); } }); } 

Il existe en réalité plusieurs solutions, selon le scénario:

  1. La méthode sûre fonctionnera juste avant de dessiner la vue, une fois la phase de mise en page terminée:
 public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) { final OnPreDrawListener preDrawListener = new OnPreDrawListener() { @Override public boolean onPreDraw() { view.getViewTreeObserver().removeOnPreDrawListener(this); runnable.run(); return true; } }; view.getViewTreeObserver().addOnPreDrawListener(preDrawListener); } 

Exemple d’utilisation:

  ViewUtil.runJustBeforeBeingDrawn(yourView, new Runnable() { @Override public void run() { //Here you can safely get the view size (use "getWidth" and "getHeight"), and do whatever you wish with it } }); 
  1. Dans certains cas, il suffit de mesurer manuellement la taille de la vue:
 view.measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); int width=view.getMeasuredWidth(); int height=view.getMeasuredHeight(); 
  1. Si vous avez une vue personnalisée que vous avez étendue, vous pouvez obtenir sa taille sur la méthode “onMeasure”, mais je pense que cela ne fonctionne bien que dans certains cas:
 protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { final int newHeight= MeasureSpec.getSize(heightMeasureSpec); final int newWidth= MeasureSpec.getSize(widthMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } 
  1. Si vous écrivez dans Kotlin, vous pouvez utiliser la fonction suivante, qui fonctionne en coulisse exactement comme runJustBeforeBeingDrawn que j’ai écrit:

     view.doOnPreDraw { actionToBeTriggered() } 

    Notez que vous devez append ceci à gradle (trouvé via ici ):

     implementation 'androidx.core:core-ktx:#.#' 

getWidth() -vous getWidth() avant que la vue ne soit réellement getWidth() à l’écran?

Une erreur fréquente des nouveaux développeurs Android est d’utiliser la largeur et la hauteur d’une vue dans son constructeur. Lorsque le constructeur d’une vue est appelé, Android ne connaît pas encore la taille de la vue, de sorte que les tailles sont définies sur zéro. Les tailles réelles sont calculées lors de la phase de mise en page, qui se produit après la construction, mais avant que rien ne soit dessiné. Vous pouvez utiliser la méthode onSizeChanged() pour être averti des valeurs lorsqu’elles sont connues ou vous pouvez utiliser les getWidth() et getHeight() ultérieurement, comme dans la méthode onDraw() .

Sur la base des conseils de @mbaird, j’ai trouvé une solution viable en sous- ImageView classe onLayout() et en onLayout() . J’ai ensuite créé une interface d’observateur que mon activité a implémentée et lui a transmis une référence à la classe, ce qui lui a permis de déterminer l’activité à la fin du dimensionnement.

Je ne suis pas convaincu à 100% que c’est la meilleure solution (je ne marque donc pas cette réponse comme étant correcte pour le moment), mais elle fonctionne et, d’après la documentation, c’est la première fois que l’on trouve la taille réelle d’une vue.

Voici le code pour obtenir la mise en page en remplaçant une vue si l’API <11 (API 11 inclut la fonctionnalité View.OnLayoutChangedListener):

 public class CustomListView extends ListView { private OnLayoutChangedListener layoutChangedListener; public CustomListView(Context context) { super(context); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (layoutChangedListener != null) { layoutChangedListener.onLayout(changed, l, t, r, b); } super.onLayout(changed, l, t, r, b); } public void setLayoutChangedListener( OnLayoutChangedListener layoutChangedListener) { this.layoutChangedListener = layoutChangedListener; } } public interface OnLayoutChangedListener { void onLayout(boolean changed, int l, int t, int r, int b); } 

Vous pouvez vérifier cette question . Vous pouvez utiliser la méthode post () de View .

Cela fonctionne pour moi dans mon onClickListener :

 yourView.postDelayed(new Runnable() { @Override public void run() { yourView.invalidate(); System.out.println("Height yourView: " + yourView.getHeight()); System.out.println("Width yourView: " + yourView.getWidth()); } }, 1); 

J’ai également été perdu autour de getMeasuredWidth() et de getMeasuredHeight() getHeight() et getWidth() pendant longtemps …….. plus tard, j’ai trouvé que la largeur et la hauteur de la onSizeChanged() dans onSizeChanged() les meilleures. façon de faire cela …….. vous pouvez obtenir dynamicment votre largeur onSizeChanged( et hauteur onSizeChanged( de votre vue en onSizeChanged( méthode onSizeChanged( ).

pourrait vouloir regarder ce qui a un extrait de code élaboré. New Blog Post: comment obtenir les dimensions en largeur et en hauteur d’un CustomView (extend View) sous Android http://syedrakibalhasan.blogspot.com/2011/02/how-to-get-width-and-height-dimensions.html

Utilisez ci-dessous le code, c’est donner la taille de la vue.

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); Log.e("WIDTH",""+view.getWidth()); Log.e("HEIGHT",""+view.getHeight()); } 

travaille perfekt pour moi:

  protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); CTEditor ctEdit = Element as CTEditor; if (ctEdit == null) return; if (e.PropertyName == "Text") { double xHeight = Element.Height; double aHaight = Control.Height; double height; Control.Measure(LayoutParams.MatchParent,LayoutParams.WrapContent); height = Control.MeasuredHeight; height = xHeight / aHaight * height; if (Element.HeightRequest != height) Element.HeightRequest = height; } }