Android getmeasuredheight() 和 getmeasuredwidth() 在 View.measure() 之后返回 0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24430429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:07:27  来源:igfitidea点击:

getmeasuredheight() and getmeasuredwidth() returns 0 after View.measure()

androidlayoutview

提问by SathMK

After measuring a Viewwith a constant dimensionswith view.measure(), the getMeasuredHeight()and getMeasureWidth()is returning 0.

测量后View具有恒定的尺寸view.measure()中,getMeasuredHeight()并且getMeasureWidth()将返回0。

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

layout_view.xml,膨胀以创建视图的布局

<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());

}

回答by Francis Shi

When you call view.getMeasuredWidth()in onCreate()or onCreateView(), the viewhas not been drawn yet. So you need to add a listener and will get a callback when the viewis being drawn. Just like this in my code:

当你打电话view.getMeasuredWidth()onCreate()还是onCreateView(),在view还没有被抽呢。所以你需要添加一个监听器,并且view在绘制时会得到一个回调。就像在我的代码中这样:

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.removeOnGlobalLayoutListener(this)删除侦听器。像这样调用它:

vto.getViewTreeObserver()

回答by Giru Bhai

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.

您是否正在测量onCreate(). 视图尚未绘制。您必须等到视图绘制后一段时间才能对其进行测量。

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

对此的简单解决方案是将 runnable 发布到布局。runnable 将在布局发生后执行。

For more info See this post

有关更多信息,请参阅此帖子

Edittry to change

编辑尝试改变

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

to

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

回答by Haresh Chhelana

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();

   }
});

回答by Radu Simionescu

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.

如果您的测量视图将可见性设置为消失,则测量将返回 0。您可以将其设置为可见、测量,然后设置回消失,所有这些都来自代码。

回答by M-WaJeEh

You can not use View.MeasureSpec.*directly in measurecall. Instead first makeMeasureSpec()and then use it to invoke measure():

不能View.MeasureSpec.*直接在measure通话中使用。而是首先makeMeasureSpec()然后使用它来调用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);

回答by Ильнар Хафизов

Just in case someone was experiencing this problem with ImageView:

以防万一有人在使用 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.

我注意到如果您的 ImageView 没有设置“android:src”(即您动态更改它),它将始终从 getMeasuredWidth/Height 返回零。

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

一个简单的解决方法是为视图设置占位符。

回答by CoolMind

You can use getViewTreeObserverin onCreate/onCreateViewand other events.

您可以使用getViewTreeObserverinonCreate/onCreateView和其他事件。

fun setGlobalLayoutListener(view: View, method: () -> Unit) {
    val vto1 = view.viewTreeObserver
    if (vto1.isAlive) {
        vto1.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                val vto2 = view.viewTreeObserver
                if (vto2.isAlive) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        vto2.removeOnGlobalLayoutListener(this)
                    } else {
                        @Suppress("DEPRECATION")
                        vto2.removeGlobalOnLayoutListener(this)
                    }
                    // Your actions are here:
                    method()
                }
            }
        })
    }
}

And call it: setGlobalLayoutListener(view) {updateUI(view)}.

并称之为:setGlobalLayoutListener(view) {updateUI(view)}

I also tried

我也试过

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

and then called view.control.measuredWidthin onCreateView()/onViewCreated(). But in some emulators (API 19) it returned wrong results.

然后叫view.control.measuredWidthonCreateView()/onViewCreated()。但是在某些模拟器(API 19)中,它返回了错误的结果。