Подтвердить что ты не робот

Исключение нулевого указателя при вызове меры на раздутом макете

Итак, у меня есть макет, который является отдельным файлом, поэтому я раздуваю его. Затем я меняю свои текстовые представления и изображение в своем макете и вызывая меру, но при попытке измерить макет получаю нулевой указатель. Я не могу для жизни понять, почему это так. В конце концов, я пытаюсь преобразовать макет в растровое изображение.

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 дают допустимые значения.

Любые идеи?

Спасибо!

4b9b3361

Ответ 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