22 votes

Exception de pointeur nul lors de l'appel d'une mesure sur un modèle gonflé

J'ai donc une mise en page qui est un fichier séparé, que je gonfle. Ensuite, je modifie mes vues de texte et mon image dans ma mise en page, et j'appelle la mesure, mais j'obtiens un pointeur nul lorsque j'essaie de mesurer la mise en page. Je n'arrive pas à comprendre pourquoi. J'essaie de convertir la mise en page en une image bitmap.

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

Voici le fichier 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>

À la ligne measure(), il lance un pointeur nul, et j'ai vérifié que getWidth et getHeight donnent des valeurs légitimes.

Des idées ?

Merci !

39voto

AZ_ Points 7127

measure() lancers Null Pointer Exception parce que lorsque vous gonflez votre mise en page, il ne lira pas les propriétés de hauteur et de largeur de la mise en page.

Il suffit d'ajouter cette ligne avant d'appeler view.measure() en fonction du type d'agencement que vous utilisez

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

34voto

Eric Ruck Points 151

Le RelativeLayout de niveau supérieur semble s'affoler sur les mesures sans limites. Définir des limites explicites sur la vue gonflée avant d'appeler la mesure :

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

11voto

Keyhan Asghari Points 1502

Inflater n'extrait pas layout_width y layout_height lorsque vous n'assignez pas son parent comme argument dans l'attribut inflate essayez donc de définir la méthode LayoutParams avec la largeur et la hauteur spécifiées, puis appeler la mesure.

1voto

Kaj Points 6802

Je ne sais pas pourquoi vous gonflez à la main et pourquoi vous voulez sauvegarder une image. Mais je fais presque la même chose dans une mise en page complexe pour un widget d'écran d'accueil, et voici ce que je fais :

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

1voto

CoatedMoose Points 733

Bien que j'aie constaté que le réglage des paramètres de mise en page (comme dans plusieurs autres réponses) a résolu mon problème, la solution que j'ai utilisée s'est avérée être que les vues ont été gonflées avec des

inflater.inflate(layoutId, null);

au lieu de

inflater.inflate(layoutId, parent, false);

Cette solution était plus adaptée à mon cas d'utilisation puisqu'il y avait en fait un parent et que les paramètres de mise en page du parent pouvaient être utilisés et respectés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X