java 在膨胀的布局上调用度量时出现空指针异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5940150/
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-10-30 13:34:44  来源:igfitidea点击:

Null pointer exception when calling measure on inflated layout

javaandroidandroid-layout

提问by rozap

So I have a layout that is a separate file, so I inflate it. Then I change my text views and image in my layout, and call measure, but I get a null pointer when I try to measure the layout. I cannot for the life of me figure out why this is. I'm trying to convert the layout to a bitmap eventually.

所以我的布局是一个单独的文件,所以我对其进行了膨胀。然后我更改布局中的文本视图和图像,并调用 measure,但是当我尝试测量布局时得到一个空指针。我一生都无法弄清楚为什么会这样。我试图最终将布局转换为位图。

View inflatedView  = ((Activity)getContext()).getLayoutInflater().inflate(R.layout.my_layout, null);

inflatedView.measure(getWidth(), getHeight());
inflatedView.layout(0, 0, inflatedView.getMeasuredWidth(),inflatedView.getMeasuredHeight());
Bitmap viewAsImage = Bitmap.createBitmap(inflatedView.getWidth(), inflatedView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas viewCanvas = new Canvas(viewAsImage);

Here is the XML

这是 XML

<RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:layout_gravity="bottom"
    android:id="@+id/my_layout"
    android:background="@color/transparent_black">
    <ImageView android:id="@+id/image_left"
        android:layout_width="48dip" android:layout_height="48dip"
        android:layout_centerVertical="true" android:layout_alignParentLeft="true"
        android:scaleType="fitXY" android:maxWidth="48dip" android:maxHeight="48dip"
        android:padding="5dip" />
    <ImageView android:id="@+id/image_right"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_marginRight="20dip" android:src="@drawable/arrow"
        android:layout_centerVertical="true" android:scaleType="fitXY"
        android:maxWidth="48dip" android:maxHeight="48dip"
        android:layout_alignParentRight="true" />
    <TextView android:paddingLeft="4dip" android:paddingRight="1dip"
        android:layout_width="wrap_content"         android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image_left"
        android:layout_toLeftOf="@id/image_right"       android:id="@+id/some_name"
        android:maxLines="1" android:ellipsize="end" android:textSize="20sp"
        android:textColor="@color/white"
                    android:layout_centerVertical="true"
        android:textStyle="normal" />
</RelativeLayout>

At the measure() line, it throws a null pointer, and I have verified that getWidth and getHeight are giving legitimate values.

在 measure() 行,它抛出一个空指针,我已经验证 getWidth 和 getHeight 给出了合法的值。

Any ideas?

有任何想法吗?

Thanks!

谢谢!

回答by AZ_

measure()throws Null Pointer Exceptionbecause when you inflate you layout it won't read layout height width properties.

measure()抛出Null Pointer Exception是因为当你膨胀你的布局时,它不会读取布局高度宽度属性。

Just add this line before calling view.measure()depending upon type of layout you are using

view.measure()根据您使用的布局类型,在调用之前添加此行

v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

public Bitmap getBitmapFromView(RelativeLayout v) {
        v.setLayoutParams(new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
        v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas c = new Canvas(b);
        v.draw(c);
        return b;
    }

回答by Eric Ruck

The top level RelativeLayout seems to freak out on measure without boundaries. Set explicit boundaries on the inflated view before calling measure:

顶级的 RelativeLayout 似乎在没有边界的情况下吓坏了。在调用 measure 之前在膨胀视图上设置明确的边界:

v.setLayoutParams(new ViewGroup.LayoutParams(0,0));

回答by Keyhan Asghari

Inflaterdoes not extract layout_widthand layout_heightattributes when you don't assign its parent as an argument in inflatemethod, so try to set LayoutParamswith specified width and height and then call measure.

Inflater当您在方法中未将其父项指定为参数时,不会提取layout_widthlayout_height属性inflate,因此请尝试LayoutParams使用指定的宽度和高度进行设置,然后调用测量。

回答by Kaj

I don't know why you are inflating by hand, and why you want to save an image of it. But I'm doing almost the same thing in a complex layout for a home screen widget, and this is what I do:

我不知道你为什么要手动充气,为什么要保存它的图像。但是我在主屏幕小部件的复杂布局中做几乎相同的事情,这就是我所做的:

LayoutInflater inflater = LayoutInflater.from(context);
View content = inflater.inflate(layoutId, null);
int measuredWidth = View.MeasureSpec.makeMeasureSpec(widgetWidth, View.MeasureSpec.EXACTLY); 
int measuredHeight = View.MeasureSpec.makeMeasureSpec(widgetHeight, View.MeasureSpec.EXACTLY);
content.measure(measuredWidth, measuredHeight); 
content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(widgetWidth, widgetHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
File file = new File(bitmapCacheFileName);              
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.close();

回答by CoatedMoose

While I found that setting layout parameters (as in several other answers) did fix my problem, the solution I used ended up being that the views were inflated with

虽然我发现设置布局参数(如在其他几个答案中)确实解决了我的问题,但我使用的解决方案最终是视图被膨胀

inflater.inflate(layoutId, null);

instead of

代替

inflater.inflate(layoutId, parent, false);

This was more correct for my use case since there was actually a parent and the layout parameters of the parent could be used and respected.

这对我的用例来说更正确,因为实际上有一个父级,并且可以使用和尊重父级的布局参数。

回答by Manuel Schmitzberger

I fix it with adding:

我通过添加来修复它:

view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,desiredHeight));

to the view before returning it from InfoWindowAdapter.getInfoWindow

在从 InfoWindowAdapter.getInfoWindow 返回之前到视图

(from: https://stackoverflow.com/a/15750783/4291264)

(来自:https: //stackoverflow.com/a/15750783/4291264

回答by MohanRaj S

Just found out that testing device or emulator android version < 4.4 this generates a nullpointer exception. Changing the layout with a Linear one will solve the problem.Here i changed your code.
Code:

刚刚发现测试设备或模拟器 android 版本 < 4.4 这会生成空指针异常。使用 Linear 更改布局将解决问题。我在这里更改了您的代码。
代码:

<LinearLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:layout_gravity="bottom"
    android:background="@color/transparent_black">

    <ImageView android:id="@+id/image_left"
        android:layout_width="48dip" 
        android:layout_height="48dip"
        android:layout_centerVertical="true"      
        android:layout_alignParentLeft="true"
        android:scaleType="fitXY"
        android:maxWidth="48dip"
        android:maxHeight="48dip"
        android:padding="5dip" />
    <ImageView android:id="@+id/image_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dip"
        android:src="@drawable/arrow"
        android:layout_centerVertical="true"
        android:scaleType="fitXY"
        android:maxWidth="48dip"
        android:maxHeight="48dip"
        android:layout_alignParentRight="true" />
    <TextView android:paddingLeft="4dip"
        android:paddingRight="1dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image_left"
        android:layout_toLeftOf="@id/image_right"
        android:id="@+id/some_name"
        android:maxLines="1"
        android:ellipsize="end"
        android:textSize="20sp"
        android:textColor="@color/white"
        android:layout_centerVertical="true"
        android:textStyle="normal" />
</RelativeLayout>

回答by namezhouyu

Change

改变

View inflatedView  = ((Activity)getContext()).getLayoutInflater().inflate(R.layout.my_layout, null);

To

View inflatedView  = ((Activity)getContext()).getLayoutInflater().inflate(R.layout.my_layout, null,false);
 inflatedView.setLayoutParams(new RelativeLayout.LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT));

If crash while invoking view.measure() method using the api below android 4.3

如果在使用 android 4.3 下面的 api 调用 view.measure() 方法时崩溃