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

时间:2011-05-09 17:06:28

标签: java android android-layout

所以我的布局是一个单独的文件,所以我给它充气。然后我在我的布局中更改我的文本视图和图像,并调用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);

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

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

有什么想法吗?

谢谢!

8 个答案:

答案 0 :(得分:39)

measure()抛出Null Pointer Exception因为当您为布局充气时,它将无法读取布局高度宽度属性。

在调用view.measure()之前添加此行,具体取决于您使用的布局类型

  

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

答案 1 :(得分:34)

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

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

答案 2 :(得分:11)

当您未在Inflater方法中将其父级作为参数分配时,

layout_width不会提取layout_heightinflate属性,因此请尝试设置LayoutParams用指定的宽度和高度然后调用measure。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

虽然我发现设置布局参数(与其他几个答案一样)确实解决了我的问题,我使用的解决方案最终是视图被夸大了

[
    {
        "key": "ctrl+s",          
        "command": "workbench.action.tasks.build" 
    }
]

而不是

inflater.inflate(layoutId, null);

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

答案 5 :(得分:1)

我通过添加:

来修复它
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,desiredHeight));
在从InfoWindowAdapter.getInfoWindow

返回视图之前

到视图

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

答案 6 :(得分:1)

刚刚发现测试设备或模拟器的android版本&lt; 4.4这会生成一个nullpointer异常。使用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>

答案 7 :(得分:0)

更改

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

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

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