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

问题描述 投票:14回答:6

在用View测量具有恒定尺寸的view.measure()之后,getMeasuredHeight()getMeasureWidth()返回0。

layout_view.xml,为了创建视图而膨胀的布局

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

测量尺寸的功能

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

}
android layout view
6个回答
9
投票

当您在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);
            }
        }
    });
}

注意:删除侦听器以获得更好的性能!

不要调用vto.removeOnGlobalLayoutListener(this)来删除监听器。像这样称呼它:

vto.getViewTreeObserver()

4
投票

你在onCreate()测量视图吗?视图尚未绘制。您必须等到视图绘制后的某个时间才能进行测量。

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

有关更多信息See this post

编辑尝试更改

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

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

3
投票

试试这种方式,希望这可以帮助您解决问题。

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

   }
});

1
投票

如果您的测量视图的可见性设置为已消失,则测量将返回0.您可以将其设置为可见,测量,然后设置回去,全部来自代码。


0
投票

以防万一有人在使用ImageView时遇到此问题:

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

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


0
投票

你不能在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);

0
投票

onCreateView()/onViewCreated()你可以使用:

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

然后打电话给view.control.measuredWidth

在其他事件,如onClick()(当视图可见和测量时),您可以简单地调用view.control.measuredWidth(没有view.measure(...))或像getViewTreeObserver一样使用getWidth() returns 0 if set by android:layout_width="match_parent"

© www.soinside.com 2019 - 2024. All rights reserved.