getmeasuredheight() and getmeasuredwidth() returns

2019-04-04 15:48发布

After measuring a View with a constant dimensions with view.measure(), the getMeasuredHeight() and getMeasureWidth() is returning 0.

layout_view.xml, layout which is inflated to create the view

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

function which measures the 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());

}

6条回答
Animai°情兽
2楼-- · 2019-04-04 15:55

Just in case someone was experiencing this problem with ImageView:

I noticed that if your ImageView doesn't have "android:src" set (i.e. you change it dynamically) it will always return zero from getMeasuredWidth/Height.

A simple workaround would be to set a placeholder for view.

查看更多
倾城 Initia
3楼-- · 2019-04-04 16:10

Try this way,hope this will help you to solve your problem.

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

   }
});
查看更多
Root(大扎)
4楼-- · 2019-04-04 16:10

if your measured view has visibility set to gone, measuring will return 0. You can set it to visible, measure, and then set back to gone, all from code.

查看更多
欢心
5楼-- · 2019-04-04 16:12

When you call view.getMeasuredWidth() in onCreate() or onCreateView(), the view has not been drawn yet. So you need to add a listener and will get a callback when the view is being drawn. Just like this in my 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: Remove the listener for better performance!

Don't call vto.removeOnGlobalLayoutListener(this) to remove the listener. Call it like this:

vto.getViewTreeObserver()
查看更多
劳资没心,怎么记你
6楼-- · 2019-04-04 16:14

You can not use View.MeasureSpec.* directly in measure call. Instead first makeMeasureSpec() and then use it to invoke 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);
查看更多
神经病院院长
7楼-- · 2019-04-04 16:22

Are you measuring the view in onCreate(). The view isn't drawn yet. You have to wait until a time after the view is drawn before you can measure it.

Simple solution for this is to post a runnable to the layout. The runnable will be executed after the layout has happened.

For more info See this post

Edit try to change

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

to

view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
查看更多
登录 后发表回答