cleverCorvid
cleverCorvid

Reputation: 13

Android SurfaceView in Custom Class

So I keep running into a NullPointerException with a project I am doing in Android Studio. I need to get an image to show up in a custom class I'm calling DrawSurface. I just can't seem to find anything that relates to my issue. I've checked various previous questions and watched so many videos.

The error I'm thrown looks like this:

java.lang.NullPointerException   at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1269)   at android.graphics.Canvas.drawBitmap(Canvas.java:1325)   at edu.########.#####.cse.treasurehunter.###########.DrawSurface.onDraw_Original(DrawSurface.java:60)   at edu.########.#####.cse.treasurehunter.###########.DrawSurface.onDraw(DrawSurface.java:-1)

My .xml looks like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".MainActivity">
<edu.########.####.cse.treasurehunter.###########.DrawSurface android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/dsField"/>
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="50dp">
    <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:text="View Inventory" android:id="@+id/btnInventory"/>
    <Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:text="Credits" android:id="@+id/btnCredits"/>
</LinearLayout>

And my DrawSurface class looks like this:

public class DrawSurface extends SurfaceView {
private Bitmap mBMPField;
private SurfaceHolder holder;

public DrawSurface(Context context) {
    super(context);
    holder = getHolder();
    holder.addCallback(new SurfaceHolder.Callback() {

        @Override
        public void surfaceCreated(SurfaceHolder holder) {

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Canvas c = holder.lockCanvas();
            onDraw(c);
            holder.unlockCanvasAndPost(c);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    });
    mBMPField = BitmapFactory.decodeResource(getResources(), R.drawable.field);
}

public DrawSurface(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public DrawSurface(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.DKGRAY);
    canvas.drawBitmap(mBMPField, 100, 200, null);
}

}

Upvotes: 1

Views: 781

Answers (2)

cleverCorvid
cleverCorvid

Reputation: 13

Ok so what happened was I didn't have an initialization function stated within my constructor. So once I started using Init(); I got it working. Thank you again for the pointers and direction. Without it I wouldn't have noticed this part.

Upvotes: 0

fadden
fadden

Reputation: 52303

  1. Don't override onDraw() if your goal is to draw on the SurfaceView's Surface (as opposed to the SurfaceView's View). onDraw() is for custom views. If you really want to use a Surface, name the method something else.
  2. Don't draw only in surfaceChanged() unless you're posting a static image. That method will usually be called once, when the Surface is first created, unless something changes the Surface's size. If you just want a static image from a Bitmap, consider using an ImageView instead.
  3. Don't assume lockCanvas() will succeed. You're pretty safe calling it from surfaceChanged(), but in general you'll want to check the return value.
  4. Don't assume BitmapFactory.decodeResource() will succeed.

Since your drawColor() call is succeeding, and your drawBitmap() call is failing, my guess is that mBMPField is null. According to the docs for decodeResource():

[Returns] The decoded bitmap, or null if the image data could not be decoded, ...

It's returning null on error, not throwing an exception, so you'll need to check the return value.

Upvotes: 1

Related Questions