Saturday, February 23, 2013

Android beginner tutorial: Part 91 - Drawing on Canvas

Today we'll see how to draw on Canvas in Android.

As I mentioned before, drawing on Canvas is usually done in performance intensive applications like video games.

There are 2 ways to draw things on a canvas in Android - the first one is to draw on a View, the second way is to draw on a SurfaceView.

Drawing on a View is more suitable when your application does not need to update the screen really fast. It can be used for a game of chess or a similar slow-paced application. The Android system provides a Canvas object that will display our graphics in a View.

To use this method, you need to create a custom class that extends View and has the onDraw() callback method. The onDraw() method is called by Android to tell your View to update its graphics. This is where you can put all the code that draws things using the Canvas type object that is passed as the parameter to this function. The class has a set of methods for drawing that you can use, which include drawBitmap(), drawRect(), drawText() and others.

Note, however, that Android will only call onDraw() of your View if it is necessary. If you decide your application is ready to be drawn, you need to call the View's invalidate() method. This tells Android that the contents should be redrawn. However, using this method does not guarantee that the redraw will occur instantly.

What's interesting is that other classes also have draw() method, which lets you take those Drawables and pass them onto the Canvas to be drawn there.

The other way to draw on a canvas is using the SurfaceView class.

This subclass of View lets us create a dedicated drawing surface inside a View, which is treated just like any other View in the application. This surface is offered a separate thread where all the drawing happens, so our main application thread does not hold it back from updating.

In this case you will also need to create a custom class. This time it extends SurfaceView. It should also implement SurfaceHolder.Callback class. This subclass is used to inform you when the underlying Surface dispatches an event, for example, when it is created or changed.

The secondary thread should be defined inside your SurfaceView class. You shouldn't handle the Surface object directly - it can be done using SurfaceHandler. When the SurfaceView object is initialized, you can access the SurfaceHolder object using getHolder() method. Then you tell SurfaceHolder that you want to receive SurfaceHolder callbacks from SurfaceHolder.Callback by calling addCallback(this).

You can then override all the SurfaceHolder.Callback methods inside your SurfaceView class. Those methods are surfaceChanged, surfaceCreated and surfaceDestroyed.

To draw to the SurfaceCanvas from withing your secondary thread, pass the SurfaceHandler object to the thread and retrieve the Canvas with lockCanvas(). You can then take and use the Canvas to draw on it. When you're done drawing, call unlockCanvasAndPost(), passing it your Canvas object. The Surface then draws the Canvas. You need to lock and unlock every time you want to update the screen.

That's all for today. We haven't written a single line of code today but hopefully you now understand the basic mechanism behind drawing graphics in Android. The code itself is pretty self explanatory and will be shown in future tutorials as practical examples.

Thanks for reading!

No comments:

Post a Comment