Balázs Édes
Balázs Édes

Reputation: 13807

Android cannot update SurfaceView in onCreate()?

What i'm trying to do, is to create a drawing app, with a SurfaceView. My app is basically done, but one thing is missing: I cannot get the SurfaceView to draw itself in the onCreate of its activity.

My SurfaceView derived class looks like this (just the important parts):

class DrawingSurface extends SurfaceView implements OnTouchListener
{ 
    SurfaceHolder holder;
    public DrawingSurface(Context context)
    {
        super(context);
        holder = getHolder();
    }
    // this method does the painting.
    public void paint()
    {
        Canvas canvas = holder.lockCanvas();
        //draw a bunch of stuff
        holder.unlockCanvasAndPost(canvas);
    }

    //in the onTouch method i call the paint() without any problem
}

And the onCreate of the Activity:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    surface = new DrawingSurface(this);
    setContentView(surface);
    //surface.paint(); <--- here is the problem
}

So as you can see the code is pretty standard, but if i try to use the surface.paint() in the onCreate(), then i get a NullPointerException, because at that time, the SurfaceHolder returns null for the lockCanvas call.

So how can i solve this problem? I want this paint method to run at the beginning of the Activity, because otherwise the background only gets painted, when the user starts drawing. What i tried:

I have really no idea, why this happens, otherwise everything seems to work.

Upvotes: 0

Views: 2383

Answers (1)

Krylez
Krylez

Reputation: 17800

Try a different model. Do all the painting inside the SurfaceView

public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
    public DrawingSurface(Context context) {
        super(context);
        getHolder().addCallback(this);
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
        updatePanel();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        updatePanel();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        updatePanel();
    }

    public void updatePanel() {
        Canvas canvas = null;
        try {
            canvas = getHolder().lockCanvas(null);
            synchronized (getHolder()) {
                doDraw(canvas);
            }
        }
        finally {
            if (canvas != null) {
                getHolder().unlockCanvasAndPost(canvas);
            }
        }
    }
}

You'd also call the updatePanel method in your touch listener.

All your painting goes in the doDraw method, which is never called outside the SurfaceView. Also, be sure you do a null check in the doDraw on the Canvas object before trying to draw anything.

Upvotes: 1

Related Questions