Исключение нулевого указателя при вызове меры на раздутом макете
Итак, у меня есть макет, который является отдельным файлом, поэтому я раздуваю его. Затем я меняю свои текстовые представления и изображение в своем макете и вызывая меру, но при попытке измерить макет получаю нулевой указатель. Я не могу для жизни понять, почему это так. В конце концов, я пытаюсь преобразовать макет в растровое изображение.
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 дают допустимые значения.
Любые идеи?
Спасибо!
Ответы
Ответ 1
measure()
throws 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;
}
Ответ 2
Верхний уровень RelativeLayout, похоже, волнуется по мере без границ. Установите четкие границы на завышенном представлении до вызова меры:
v.setLayoutParams(new ViewGroup.LayoutParams(0,0));
Ответ 3
Inflater
не извлекает атрибуты layout_width
и layout_height
, если вы не назначаете его родительский аргумент в методе inflate
, поэтому попробуйте установить LayoutParams
с указанной шириной и высотой, а затем вызвать меру.
Ответ 4
Я не знаю, почему вы раздуваете вручную, и почему вы хотите сохранить его изображение. Но я делаю почти то же самое в сложной компоновке для виджета на главном экране, и это то, что я делаю:
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();
Ответ 5
В то время как я обнаружил, что параметры настройки макета (как и в нескольких других ответах) устранили мою проблему, решение, которое я использовал, оказалось тем, что представления были завышены с помощью
inflater.inflate(layoutId, null);
вместо
inflater.inflate(layoutId, parent, false);
Это было более правильным для моего случая использования, поскольку на самом деле был родитель, и параметры макета родителя можно было использовать и уважать.
Ответ 6
Я исправляю это с добавлением:
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,desiredHeight));
прежде чем возвращать его из InfoWindowAdapter.getInfoWindow
(from: fooobar.com/questions/244901/...)
Ответ 7
Просто выяснилось, что тестовое устройство или версия android-эмулятора, 4.4 это генерирует исключение nullpointer. Изменение макета с помощью линейного решения будет решить проблему. Здесь я изменил код.
Код:
<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>
Ответ 8
Изменить
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));
Если сбой при вызове метода view.measure() с использованием api ниже android 4.3