web-dev-qa-db-fra.com

getmeasuredheight () et getmeasuredwidth () est renvoyé après View.measure ()

Après avoir mesuré une View avec une dimensions constantes avec view.measure(), les fonctions getMeasuredHeight() et getMeasureWidth() renvoient 0.

layout_view.xml , disposition gonflée pour créer la vue

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" 
    Android:layout_width="100dp"
    Android:layout_height="100dp">
</FrameLayout>

fonction qui mesure les dimensions

public void measureView(Context context){
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.layout_view,null,false);

    view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

    Log.d(TAG,"Error width : " + view.getMeasuredWidth());
    Log.d(TAG,"Error heeght : " + view.getMeasuredHeight());

}
11
SathMK

Lorsque vous appelez view.getMeasuredWidth() dans onCreate() ou onCreateView(), la view n'a pas encore été dessinée. Vous devez donc ajouter un auditeur et obtenir un rappel lorsque la variable view est en cours d’extraction. Juste comme ça dans mon code: 

final ViewTreeObserver vto = view.getViewTreeObserver();
if (vto.isAlive()) {
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int viewWidth = view.getMeasuredWidth();
            // handle viewWidth here...

            if (Build.VERSION.SDK_INT < 16) {
                vto.removeGlobalOnLayoutListener(this);
            } else {
                vto.removeOnGlobalLayoutListener(this);
            }
        }
    });
}

NOTE: Supprimez l'auditeur pour de meilleures performances!

N'appelez pas vto.removeOnGlobalLayoutListener(this) pour supprimer l'auditeur. Appelez ça comme ça: 

vto.getViewTreeObserver()
9
Francis Shi

Mesurez-vous la vue dans onCreate(). La vue n'est pas encore dessinée. Vous devez attendre un certain temps après le dessin de la vue avant de pouvoir la mesurer.

La solution simple pour cela consiste à poster un exécutable à la mise en page. Le runnable sera exécuté après la mise en page.

Pour plus d'informations Voir cet article

Edit Essayez de changer

view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

à

view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
4
Giru Bhai

Essayez de cette façon, espérons que cela vous aidera à résoudre votre problème.

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
     int width = view.getMeasuredWidth();
     int height = view.getMeasuredHeight();

   }
});
3
Haresh Chhelana

si la visibilité de votre vue mesurée est définie sur parti, la mesure retournera 0. Vous pouvez la définir sur visible, mesurer, puis redéfinie sur «disparu», le tout à partir du code.

1
Radu Simionescu

Juste au cas où quelqu'un rencontrerait ce problème avec ImageView:

J'ai remarqué que si votre ImageView n'a pas "Android: src" défini (c'est-à-dire que vous le changez dynamiquement), il retournera toujours zéro à partir de getMeasuredWidth/Height. 

Une solution de contournement simple consisterait à définir un espace réservé pour la vue.

Vous ne pouvez pas utiliser View.MeasureSpec.* directement dans l'appel measure. Au lieu de cela, utilisez d'abord makeMeasureSpec(), puis utilisez-le pour appeler measure():

final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
0
M-WaJeEh