java – Null pointer exception when calling measure on inflated layout-ThrowExceptions

Exception or error:

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.

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

<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.

Any ideas?

Thanks!

How to solve:

measure() throws Null Pointer Exception because when you inflate you layout it won’t read layout height width properties.

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

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;
    }

###

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

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

###

Inflater does not extract layout_width and layout_height attributes when you don’t assign its parent as an argument in inflate method, so try to set LayoutParams with specified width and height and then call measure.

###

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

###

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.

###

I fix it with adding:

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

to the view before returning it from InfoWindowAdapter.getInfoWindow

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

###

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:

<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>

###

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

Leave a Reply

Your email address will not be published. Required fields are marked *